Dapper系列之一:Dapper的入门(多表批量插入)
Dapper介绍
简介:
不知道博客怎么去写去排版,查了好多相关博客,也根据自己做过项目总结,正好最近搭个微服务框架,顺便把搭建微服务框架所运用的知识都进行博客梳理,为了以后复习,就仔细琢磨写一下自己在微服务框架中对Dapepr的理解以及项目中应用。 dapper 只是一个代码文件,完全开源,你可以在项目里任何位置,来实现数据到对象ORM操作(当然先引用Dapper文件),体积小速度快。使用好处增删改查比较快,不用自己写sql,因为这都是重复技术含量低的工作,还有程序中大量的数据库中读取数据然后创建model,并且为model字段赋值,这都是很轻松的,个人认为Dapper可以看做HelpSQL,甚至比HelperSQL性能高一点。如果你喜欢原生的SQL,那么有喜欢ORM的简单,那你一定钟情于Dapper 并且爱上他。
Dapper的优势:
、Dapper是一个轻量级ORM类,代码就是一个SQLMapper.cs文件,编译后一般在40k左右的dll;
、Dapper快,为啥说快呢?因为Dapepr速度接近IDataReader,取列表的数据超过DataTable;
、Dapper支持什么数据库?支持Mysql,sqlLite,SQLServer,Oracle等一系列数据库,(备注:我个人在在做demo中,就是使用了Mysql,SQLServer,公司和个电脑装的数据库不一样,就都测试了);
、Dapper的R支持多表并联的对象,支持一对多,多对多关系,并且没侵入性,想用就用 ;
、Dapper原理就是通过Emit反射IDateReader的队列,来快速得到和产生对象;这也是性能高的原因之一;
、Dapper语法简单,快速入手。
如果面试,让你说出Dapper的好处,为啥用Dapper,上面回答出来,杠杠的。。。。。。。。
面试官:我靠,小伙子懂的挺多.........
在超过500次poco serialization的过程中所表现的性能,我们发现dapper是第二名,当然第一名谁也无法超越,越底层的当然久越快,同时也就越麻烦。
Dapper代码应用
第一步:
在NuGet中引用Dapper
第二步:
新建一个ConnectionFactory类,创建链接对象,這里我们封装两个方法分别获取SQLServerr 和MySQL
public class ConnectionFactory
{
//获取web 中的配置文件
private static readonly string QlwMysqlConnection = ConfigurationManager.AppSettings["sqlconnectionString"];
/// <summary>
/// sqlServer 数据库
/// </summary>
/// <returns></returns>
public static IDbConnection SqlServerConnection()
{
string sqlconnectionString = QlwMysqlConnection; //ConfigurationManager.ConnectionStrings["sqlconnectionString"].ToString();
var connection = new SqlConnection(sqlconnectionString);
if (connection.State == ConnectionState.Closed)
{
connection.Open();
}
return connection;
}
/// <summary>
/// mySQl 数据库
/// </summary>
/// <returns></returns>
public static IDbConnection MySqlConnection()
{
string mysqlconnectionString = QlwMysqlConnection; //ConfigurationManager.ConnectionStrings["mysqlconnectionString"].ToString();
var connection = new MySqlConnection(mysqlconnectionString);
if (connection.State == ConnectionState.Closed)
{
connection.Open();
}
return connection;
}
}
第三步:
(1)先看一下后台:SqlMapper,封装了给我们提供了那些方法:
(2)我们根据上面方法加一层,简单封装,为了业务更加方便:
先说说添加Insert操作,我们对Execute方法进行简单的封装:
SqlMapper提供:两个封装Execute:
(3)、创建一个DapperDBContext类
public static class DapperDBContext
{
public static List<T> AsList<T>(this IEnumerable<T> source)
{
if (source != null && !(source is List<T>))
return source.ToList();
return (List<T>)source;
}
//参数我们跟后台封装方法保持一致
public static int Execute(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null, int databaseOption = )
{
using (var conn = ConnectionFactory.MySqlConnection())
{
var info = "SQL语句:" + sql + " \n SQL参数: " + JsonConvert.SerializeObject(param) + " \n";
// LogHelper.ErrorLog(info); // 可以记录操作
var sw = new Stopwatch(); sw.Start();
var restult = conn.Execute(sql, param, transaction, commandTimeout, commandType);
sw.Stop();
LogHelper.ErrorLog(info + "耗时:" + sw.ElapsedMilliseconds + (sw.ElapsedMilliseconds > ? "#####" : string.Empty) + "\n"); // 可以记录操作
return restult;
}
} public static int Execute(CommandDefinition command, int databaseOption = )
{
using (var conn = ConnectionFactory.MySqlConnection())
{
var info = " SQL语句:" + command.CommandText + " \n SQL命令类型: " + command.CommandType + " \n";
// LogHelper.Info(info);// 可以记录操作
var sw = new Stopwatch(); sw.Start();
var restult = conn.Execute(command);
sw.Stop();
// LogHelper.Info(info + "耗时:" + sw.ElapsedMilliseconds + (sw.ElapsedMilliseconds > 1000 ? "#####" : string.Empty) + "\n");// 可以记录操作
return restult;
}
}
}
(4.1)、单条数据插入:
public class DepartmentRepository
{
/// <summary>
/// 插入单条数据以及多条数据
/// </summary>
/// <param name="department"></param>
/// <returns></returns>
public bool Add(List<Department> department, AuthResources authResources)
{
#region 插入单条数据
string sql = @" INSERT INTO Department (ID,EID,Name,Remarks,Description,Notice,ParentId,AddTime,IsDel,UpdateTime)
VALUES(@ID,@EID,@Name,@Remarks,@Description,@Notice,@ParentId,@AddTime,@IsDel,@UpdateTime); ";
var result = DapperDBContext.Execute(sql, department[]);
return result >= ;
#endregion
}
}
(4.2)、单表批量数据插入:
// department是100条数据
public bool Add(List<Department> department, AuthResources authResources)
{
#region 插入单条数据
string sql = @" INSERT INTO Department (ID,EID,Name,Remarks,Description,Notice,ParentId,AddTime,IsDel,UpdateTime)
VALUES(@ID,@EID,@Name,@Remarks,@Description,@Notice,@ParentId,@AddTime,@IsDel,@UpdateTime); ";
var result = DapperDBContext.Execute(sql, department); //直接传送list对象
return result >= ;
#endregion
}
(4.3)、多表多数据批量插入:
這里我们采用事物,事物本身有两个特有特性:原子性和统一性,比如:向ABC三个表同时插入,只要有个插入有误都失败,如果不采用事物,采用纯sql插入可能出现数据不一致,AB成功,C失败 。
那我们在DapperDBContext中继续封装一个事物的方法,不知道你现在有没有体会到,我们为啥在中间一层,为了我们根据业务的扩展而却要。
方法可以自己扩展,根据自己业务需要去延伸。。。。。
/// <summary>
/// 多表操作--事务
/// </summary>
/// <param name="trans"></param>
/// <param name="databaseOption"></param>
/// <param name="commandTimeout"></param>
/// <returns></returns>
public static Tuple<bool, string> ExecuteTransaction(List<Tuple<string, object>> trans, int databaseOption = , int? commandTimeout = null)
{
if (!trans.Any()) return new Tuple<bool, string>(false, "执行事务SQL语句不能为空!");
using (var conn = ConnectionFactory.MySqlConnection())
{
//开启事务
using (var transaction = conn.BeginTransaction())
{
try
{
var sb = new StringBuilder("ExecuteTransaction 事务: ");
foreach (var tran in trans)
{
sb.Append("SQL语句:" + tran.Item1 + " \n SQL参数: " + JsonConvert.SerializeObject(tran.Item2) + " \n");
// 根据业务添加纪录日志 LogHelper.InfoLog("SQL语句:" + tran.Item1 + " \n SQL参数: " +
JsonConvert.SerializeObject(tran.Item2) + " \n");
//执行事务
conn.Execute(tran.Item1, tran.Item2, transaction, commandTimeout);
}
var sw = new Stopwatch();
sw.Start();
//提交事务
transaction.Commit();
sw.Stop();
// 根据业务添加纪录日志 LogHelper.InfoLog(sb.ToString() + "耗时:" + sw.ElapsedMilliseconds + (sw.ElapsedMilliseconds > 1000 ?
"#####" : string.Empty) + "\n");
return new Tuple<bool, string>(true, string.Empty);
}
catch (Exception ex)
{
//todo:!!!transaction rollback can not work.
LogHelper.ErrorLog(ex);
//回滚事务
transaction.Rollback();
conn.Close();
conn.Dispose();
return new Tuple<bool, string>(false, ex.ToString());
}
finally
{
conn.Close();
conn.Dispose();
}
}
}
}
方法中用到的Tuple(元组)方法我们就不做介绍,后期我会整理一篇专门介绍元组的方法以及一些新的特性。事物同样可以满足一个表多条数据插入
public bool Add(List<Department> department, AuthResources authResources)
{
#region 事务:元组形式插入多条数据
var param = new List<Tuple<string, object>>();
Tuple<string, object> tupel;
var sw = new Stopwatch();
sw.Start();
for (int i = ; i < ; i++)
{
tupel = new Tuple<string, object>(@" INSERT INTO Department (ID,EID,Name,Remarks,Description,Notice,ParentId,AddTime,IsDel,UpdateTime) VALUES(@ID,@EID,@Name,@Remarks,@Description,@Notice,@ParentId,@AddTime,@IsDel,@UpdateTime) ", new
{
ID = Guid.NewGuid(),
EID = Guid.NewGuid(),
Name = "部门",
Remarks = "",
Description = "",
AddTime = DateTime.Now,
IsDel = ,
UpdateTime = DateTime.Now,
ParentId = Guid.NewGuid(),
Notice = "",
});
param.Add(tupel);
}
tupel = new Tuple<string, object>(@" INSERT INTO AuthResources (ID,EID,AuthId,ResourceId,AddTime,IsDel,UpdateTime) VALUES(@ID,@EID,@AuthId,@ResourceId,@AddTime,@IsDel,@UpdateTime) ", new
{
ID = Guid.NewGuid(),
EId = Guid.NewGuid(),
AuthId = Guid.NewGuid(),
ResourceId = Guid.NewGuid(),
AddTime = DateTime.Now,
IsDel = ,
UpdateTime = DateTime.Now,
});
param.Add(tupel);
//调用上面我们封装的事物方法:ExecuteTransaction
var result = DapperDBContext.ExecuteTransaction(param).Item1;
sw.Stop();
return result;
#endregion
}
结果:
总结:(Dapper 还没结束,下篇正在书写中。。。。。。。)
1、插入的三种方式就结束了,如果你有更好的方法,欢迎下方留言,一起讨论,本文有不对的方法也多多指出;
2、在做的过程中,还百度相关资料,无意中发现数据遍历可以不用for和foreach,
可以用 Enumerable.Range,已测试性能,很不错,Dapper写完建立新的博客讲解。。。。
手动写东西,你会发现好多问题,大家一起边学习边总结,虽然写博客很费事,但是确实能收入不少东西,最起码你写的得到别人认可,
看得懂,如果还能推荐一下,心理满满的小激动,哈哈哈哈,好比:你学外语,不去跟别人说,沟通,怎么知道学的怎么样,博客园就是這个平台.........
- 博主是利用读书、参考、引用、抄袭、复制和粘贴等多种方式打造成自己的纯镀 24k 文章,请原谅博主成为一个无耻的文档搬运工!
- 小弟刚迈入博客编写,文中如有不对,欢迎用板砖扶正,希望给你有所帮助。
Dapper系列之一:Dapper的入门(多表批量插入)的更多相关文章
- mybatis父子表批量插入
<!--父子表批量插入 --> <insert id="insertBatch" parameterType="com.niwopay.dto.beni ...
- [入门到吐槽系列] Webix 10分钟入门 二 表单Form的使用
前言 继续接着上一篇的webix入门:https://www.cnblogs.com/zc22/p/15912342.html.今天完成剩下两个最重要的控件,表单和表格的使用.掌握了这两个,整个Web ...
- [置顶] mybatis批量新增系列之有主键的表的批量新增
前面介绍了无主键的表的批量插入,文章地址:http://blog.csdn.net/zhouxiaoyun0228/article/details/9980181 但是在开发中往往许多的表是需要主键的 ...
- 练习六 向表A批量插入数据
create or replace procedure BATCH_INSERT_A (insertNo in integer) is n_id integer; /***************** ...
- 【Oracle/Java】给十六张表各插入十万条数据 单线程耗时半小时 多线程耗时一刻钟
测试机Oracle版本: SQL> select * from v$version; BANNER ----------------------------------------------- ...
- 【Oracle/Java】向三张表各插入百万数据,共用时18分3秒,平均每张表6分钟
三张表DDL如下: CREATE TABLE tb01 ( "ID" ,) not null primary key, "NAME" NVARCHAR2() n ...
- Dapper系列之三:Dapper的事务修改与删除
Dapepr的Update和Delete Dapper入门Dapper查询 上两篇文章我们介绍Dapper中添加和查询.本篇文章我们继续讲解修改和删除....如果本篇文章看不懂,请看阅读上两篇Dapp ...
- Net系列框架-Dapper+简单三层架构
Net系列框架-Dapper+简单三层架构 工作将近6年多了,工作中也陆陆续续学习和搭建了不少的框架,后续将按由浅入深的方式,整理出一些框架源码,所有框架源码本人都亲自调试通过,如果有问题,欢迎联系我 ...
- 基于Dapper的分布式链路追踪入门——Opencensus+Zipkin+Jaeger
微信搜索公众号 「程序员白泽」,进入白泽的编程知识分享星球 最近做了一些分布式链路追踪有关的东西,写篇文章来梳理一下思路,或许可以帮到想入门的同学.下面我将从原理到demo为大家一一进行讲解,欢迎评论 ...
随机推荐
- Deep Learning 31: 不同版本的keras,对同样的代码,得到不同结果的原因总结
一.疑问 这几天一直纠结于一个问题: 同样的代码,为什么在keras的0.3.3版本中,拟合得比较好,也没有过拟合,验证集准确率一直高于训练准确率. 但是在换到keras的1.2.0版本中的时候,就过 ...
- VS1053 datasheet 解读笔记
pdf 10 pdf 11 ` 左右声道 负载,注意这里的负载指LEFT 到GBUF,RIGHT到GBUF.所以后面会有说明GBUF一定不能连接到GND. pdf 14 pdf 14 从上面的引脚定 ...
- linux初级学习笔记十:linux grep及正则表达式!(视频序号:04_4)
本节学习的命令:grep 本节学习的技能: grep对文本的匹配 正则表达式的使用 知识点十:grep及正则表达式(4_4) grep,egrep,fgrep: grep: 根据模式搜索文本,并将符合 ...
- html5--6-63 布局
html5--6-63 布局 实例 学习要点 掌握传统布局与CSS3新增布局方式的实现和应用 掌握CSS3新增属性box-sizing 了解CSS3新增的多列布局 常用布局方式 固定布局与流体布局的优 ...
- Python小练习_将数据库中表数据存到redis里
# ##练习:将xxx数据库中my_user表中数据存到redis里面# 分析: pymysql.json.redis# 1.连接数据库,查到数据库里面所有的数据,游标类型要用pymysql.curs ...
- 深入理解WeakHashmap
转自:http://mikewang.blog.51cto.com/3826268/880775 (一) 查看API文档,WeakHashmap要点如下: 1. 以弱键 实现的基于哈希表的 Map.在 ...
- Snowflake算法 ID生成
Snowflake算法 ID生成 http://blog.csdn.net/w200221626/article/details/52064976 使用UUID或者GUID产生的ID没有规则 Snow ...
- 【SOUTH CENTRAL USA 1998】 eight
[题目链接] 点击打开链接 [算法] 这是经典的八数码问题,据说此题不做人生不完整 这里笔者用的是双向广搜,由于细节较多,笔者花了3h才通过此题 [代码] #include <algorithm ...
- javascript之this指向
情况一: 如果一个函数中有this,但是没有被上一级调用,this指向window 例: function a(){ var num='11'; console.log(this.num); //u ...
- 空间数据索引RTree完全解析及Java实现
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/MongChia1993/article/details/69941783 第一部分 空间数据的背景介 ...