使用事务操作SQLite数据批量插入,提高数据批量写入速度,源码讲解
SQLite数据库作为一般单机版软件的数据库,是非常优秀的,我目前单机版的软件产品线基本上全部替换Access作为优选的数据库了,在开发过程中,有时候需要批量写入数据的情况,发现传统的插入数据模式非常慢,几千条数据的写入或者更新可能需要好几分钟时间,而SqlServer则相同的操作可能几秒即可,有无更好的方法来提高它的响应速度呢?答案是有的,就是采用事务提交,默认SQLite的数据库插入操作,如果没有采用事务的话,它每次写入提交,就会触发一次事务操作,而这样几千条的数据,就会触发几千个事务的操作,这就是时间耗费的根源。本文通过详细代码介绍如何使用事务来提高整个批量插入数据的速度,并以实际的Winform开发框架中的字典管理模块的批量插入功能来进行介绍,通过前后速度的对比,使得事务操作提高响应速度更有说服力。
由于一些项目需要,字典管理模块需要批量录入数据,因此改善了我的《Winform开发框架》中的字典管理模块,在字典管理模块增加一个批量添加的功能,如下所示。

对一些诊断的数据录入,一般情况下都可能是几千条的数据,还有可能更多的一些分类字典,那么如果每次都需要等待几分钟或者几十分钟,那么这样的响应体验肯定很差。
为了提高响应速度,我这里使用了事务操作,整个事务操作是基于EnterpriseLibray类库的数据库操作,由于我已经在框架的基类中做了封装,因此我们这里看到整个处理过程即可。

其中MyRegion里面的代码就是遍历每行的数据,构造数据字典对象和排序号,然后调用InsertDictData函数进行数据的录入。其中InsertDictData函数的代码是
/// <summary>
/// 使用事务参数,插入数据,最后统一提交事务处理
/// </summary>
/// <param name="dictData">字典数据</param>
/// <param name="seq">排序</param>
/// <param name="trans">事务对象</param>
private void InsertDictData(string dictData, string seq, DbTransaction trans)
{
if (!string.IsNullOrWhiteSpace(dictData))
{
DictDataInfo info = new DictDataInfo();
info.Editor = LoginID;
info.LastUpdated = DateTime.Now;
info.DictType_ID = this.txtDictType.Tag.ToString();
info.Name = dictData.Trim();
info.Value = dictData.Trim();
info.Remark = this.txtNote.Text.Trim();
info.Seq = seq; bool succeed = BLLFactory<DictData>.Instance.Insert(info, trans);
}
}
整个插入功能按钮的处理全部代码如下所示。
private void btnOK_Click(object sender, EventArgs e)
{
string[] arrayItems = this.txtDictData.Lines;
int intSeq = -;
int seqLength = ;
string strSeq = this.txtSeq.Text.Trim();
if (int.TryParse(strSeq, out intSeq))
{
seqLength = strSeq.Length;
} if (arrayItems != null && arrayItems.Length > )
{
DbTransaction trans = BLLFactory<DictData>.Instance.CreateTransaction();
if (trans != null)
{
try
{
#region MyRegion
foreach (string strItem in arrayItems)
{
if (this.radSplit.Checked)
{
if (!string.IsNullOrWhiteSpace(strItem))
{
string[] dataItems = strItem.Split(new char[] { ',', ',', ';', ';', '/', '、' });
foreach (string dictData in dataItems)
{
#region 保存数据
string seq = "";
if (intSeq > )
{
seq = (intSeq++).ToString().PadLeft(seqLength, '');
}
else
{
seq = string.Format("{0}{1}", strSeq, intSeq++);
} InsertDictData(dictData, seq, trans);
#endregion
}
}
}
else
{
#region 保存数据
if (!string.IsNullOrWhiteSpace(strItem))
{
string seq = "";
if (intSeq > )
{
seq = (intSeq++).ToString().PadLeft(seqLength, '');
}
else
{
seq = string.Format("{0}{1}", strSeq, intSeq++);
} InsertDictData(strItem, seq, trans);
}
#endregion
}
}
#endregion trans.Commit();
ProcessDataSaved(this.btnOK, new EventArgs());
MessageDxUtil.ShowTips("保存成功");
this.DialogResult = DialogResult.OK;
}
catch (Exception ex)
{
trans.Rollback();
LogTextHelper.Error(ex);
MessageDxUtil.ShowError(ex.Message);
}
}
}
}
上面的批量插入,经过前后的测试,2千条数据批量插入SQLite数据库,需要大概3~4分钟左右,如果采用了事务操作,则在1~2秒内写入完成,速度提高不知道多少倍。如果是操作数据比较多的,强烈建议使用事务进行操作,可以给客户很好的体验效果。
如果嫌上面的代码复杂,可以看下面的讲解代码可能就明白了
using (DbTransaction dbTrans = conn.BeginTransaction())
{
using (DbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "INSERT INTO MyTable(MyValue) VALUES(?)";
DbParameter Field1 = cmd.CreateParameter();
cmd.Parameters.Add(Field1);
for (int n = ; n < ; n++)
{
Field1.Value = n + ;
cmd.ExecuteNonQuery();
}
}
}
上面是一种比较简单原始的事务操作,如果批量插入数据,同样能够起到一样的效果。
使用事务操作SQLite数据批量插入,提高数据批量写入速度,源码讲解的更多相关文章
- SQL-35 对于表actor批量插入如下数据,如果数据已经存在,请忽略,不使用replace操作
题目描述 对于表actor批量插入如下数据,如果数据已经存在,请忽略,不使用replace操作CREATE TABLE IF NOT EXISTS actor (actor_id smallint(5 ...
- SQL-34 对于表actor批量插入如下数据
题目描述 对于表actor批量插入如下数据CREATE TABLE IF NOT EXISTS actor (actor_id smallint(5) NOT NULL PRIMARY KEY,fir ...
- .net使用SqlBulkCopy类操作DataTable批量插入数据库数据,然后分页查询坑
在使用SqlBulkCopy类操作DataTable批量插入数据,这种操作插入数据的效率很高,就会导致每一条数据在保存的时间基本一样,在我们分页查询添加的数据是,使用数据的添加时间来排序就会出现每页的 ...
- 在pycharm中批量插入表数据、分页原理、cookie和session介绍、django操作cookie
昨日内容回顾 ajax发送json格式数据 ''' 1. urlencoded 2. form-data 3. json ''' 1. ajax $.ajax({ data: JSON.stringi ...
- MySQL批量插入大量数据方法
在MySQL数据库中,如果要插入上百万级的记录,用普通的insert into来操作非常不现实,速度慢人力成本高,推荐使用Load Data或存储过程来导入数据,我总结了一些方法分享如下,主要基于My ...
- ADO.NET 新特性之SqlBulkCopy(批量插入大量数据)
转自:http://blog.csdn.net/huaer1011/article/details/2312361 在.Net1.1中无论是对于批量插入整个DataTable中的所有数据到数据库中,还 ...
- JDBC批量插入blob数据
图片从接口读取后是base64的字符串,所以转成byte数组进行保存. 我们一般保存数据的话,都是基本数据,对于这些图片数据大部分会将图片保存成Blob,Clob等. Blob存储的是二进制对象数据( ...
- .Net批量插入数据到SQLServer数据库,System.Data.SqlClient.SqlBulkCopy类批量插入大数据到数据库
批量的的数据导入数据库中,尽量少的访问数据库,高性能的对数据库进行存储. 采用SqlBulkCopy来处理存储数据.SqlBulkCopy存储大批量的数据非常的高效,将内存中的数据表直接的一次性的存储 ...
- oracle 快速批量插入复杂数据的内容
最近迷上一种批量插入的方法,一句sql解决,将需要插入的数据用with as 的方式查出来,不管多么复杂的sql,都可以用临时表的方式查出来,然后直接插入,这样代码更加清晰 流程也简单 insert ...
随机推荐
- Raw-OS源代码分析之消息系统-Queue_Size
分析的内核版本号截止到2014-04-15.基于1.05正式版.blogs会及时跟进最新版本号的内核开发进度,若源代码凝视出现"???"字样,则是未深究理解部分. Raw-OS官方 ...
- vlc android 移植版编译
同步发表于http://avenwu.net/2015/07/27/vlc-android-compiling 安装必备工具/解决环境问题 环境准备什么的如果没配置过需要一步步配置,主要是sdk/nd ...
- canvas应用-思维导图
canvas应用例子-思维导图 效果图如下: 函数说明: // 求圆上一点坐标,返回坐标点 function circlePoint(x, y, r, a) { var tmpx = x + r * ...
- session和jsessionid有什么关系
首先,并不是说你一打开一个页面就会产生一个session. 所谓session你可以这样理解:当你与服务端进行会话时,比如说登陆成功后,服务端会为你开壁一块内存区间,用以存放你这次会话的一些内容,比如 ...
- android 九宫加密记事本
自己写的超级安全记事本,用PBEWithMD5AndDES加密sqlite内容几乎无法破解, 九宫点密码登录, 支持备份到SDcard,email,network drivers etc. 附件Apk ...
- Spark源码系列(七)Spark on yarn具体实现
本来不打算写的了,但是真的是闲来无事,整天看美剧也没啥意思.这一章打算讲一下Spark on yarn的实现,1.0.0里面已经是一个stable的版本了,可是1.0.1也出来了,离1.0.0发布才一 ...
- mysql 登录后 修改密码
- 对android应用一些破解的方法
因为需要破解一款应用,找了些资料 Android手机中的程序文件夹拷贝到别的Android手机上还能用么? xx.apk Android个人破解应用新思路 安卓手机下xx.apk JAVA破解之旅 s ...
- char str[]和char *str的区别
1.http://blog.csdn.net/szchtx/article/details/10396149 char ss[]="C++"; ss[0]='c'; ...
- Query Object--查询对象模式(上)
回顾 上两篇文章主要讲解了我对于数据层的Unit Of Work(工作单元模式)的理解,其中包括了CUD的操作,那么今天就来谈谈R吧,文章包括以下几点: 什么是Query Object 基于SQL的实 ...