Sqlite使用事务插入数据

本文介绍了如何使用SQLite数据库和C#编程语言进行高效的数据插入操作。通过创建数据库文件、设置连接、创建表并批量插入数据,实现了快速的数据管理。重点展示了如何优化插入过程以提高性能。
using System.Data;
using System.Data.Common;
using System.Data.SQLite;

// 创建数据库文件
File.Delete("test1.db3");
SQLiteConnection.CreateFile("test1.db3");

DbProviderFactory factory = SQLiteFactory.Instance;
using (DbConnection conn = factory.CreateConnection())
{
  // 连接数据库
  conn.ConnectionString = "Data Source=test1.db3";
  conn.Open();

  // 创建数据表
  string sql = "create table [test1] ([id] INTEGER PRIMARY KEY, [s] TEXT COLLATE NOCASE)";
  DbCommand cmd = conn.CreateCommand();
  cmd.Connection = conn;
  cmd.CommandText = sql;
  cmd.ExecuteNonQuery();

  // 添加参数
  cmd.Parameters.Add(cmd.CreateParameter());
  
  // 开始计时
  Stopwatch watch = new Stopwatch();
  watch.Start();
  
  DbTransaction trans = conn.BeginTransaction(); // <-------------------
  try 
  {
    // 连续插入1000条记录
    for (int i = 0; i < 1000; i++)
    {
      cmd.CommandText = "insert into [test1] ([s]) values (?)";
      cmd.Parameters[0].Value = i.ToString();

      cmd.ExecuteNonQuery();
    }

    trans.Commit(); // <-------------------
  }
  catch
  {
    trans.Rollback(); // <-------------------
    throw; // <-------------------
  }

  // 停止计时
  watch.Stop();
  Console.WriteLine(watch.Elapsed);
}

使用 Qt 框架操作 SQLite 数据库时,为了提高批量插入数据的性能,可以通过事务(Transaction)机制来减少数据库的 I/O 操作次数。SQLite 默认将每条 SQL 语句视为一个独立的事务,这意味着每次插入都会触发一次完整的事务提交流程(包括日志写入、磁盘同步等),这在大量数据插入时会导致性能下降[^1]。 通过将多个插入操作合并到一个事务中,可以显著减少磁盘 I/O 和事务提交的开销,从而大幅提升插入速度。 ### 在 Qt 中使用事务进行批量插入的步骤如下: 1. **开启事务**:使用 `QSqlDatabase::transaction()` 方法手动开启事务。 2. **执行多条插入语句**:使用 `QSqlQuery` 或 `QSqlTableModel` 执行多个插入操作。 3. **提交事务**:使用 `QSqlDatabase::commit()` 提交整个事务。 4. **错误处理**:若插入过程中发生错误,可调用 `QSqlDatabase::rollback()` 回滚事务以保证数据一致性。 ### 示例代码 以下是一个使用 Qt 和事务机制进行批量插入的完整示例: ```cpp #include <QSqlDatabase> #include <QSqlQuery> #include <QSqlError> #include <QDebug> bool batchInsertWithTransaction(const QString &tableName, const QList<QPair<QString, int>> &dataList) { QSqlDatabase db = QSqlDatabase::database(); // 获取默认连接的数据库 if (!db.transaction()) { qDebug() << "Failed to start transaction:" << db.lastError().text(); return false; } QSqlQuery query; QString insertSql = QString("INSERT INTO %1 (name, age) VALUES (?, ?)").arg(tableName); if (!query.prepare(insertSql)) { qDebug() << "Failed to prepare statement:" << query.lastError().text(); db.rollback(); return false; } for (const auto &data : dataList) { query.addBindValue(data.first); query.addBindValue(data.second); if (!query.exec()) { qDebug() << "Insert failed:" << query.lastError().text(); db.rollback(); return false; } } if (!db.commit()) { qDebug() << "Commit failed:" << db.lastError().text(); db.rollback(); return false; } return true; } ``` ### 使用说明: - `tableName` 是目标表名。 - `dataList` 是包含姓名和年龄的数据列表。 - 插入前确保表结构存在,例如: ```sql CREATE TABLE IF NOT EXISTS people ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER ); ``` ### 性能优化建议: - **批量预编译**:使用 `QSqlQuery::prepare()` 配合多次 `execBatch()` 可进一步提升效率(需启用批处理支持)。 - **关闭同步(慎用)**:在非关键数据场景下,可通过设置 PRAGMA synchronous=OFF 来加快写入速度,但会降低崩溃恢复能力。 - **增加页面大小**:适当调整 SQLite 的页面大小(如 32768)有助于提升大批量写入性能。 - **使用内存数据库临时缓存**:对于超大数据量,可先插入内存数据库再导出至文件数据库。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值