Dapper系列之⼀:Dapper的⼊门(多表批量插⼊)
Dapper介绍
简介:
不知道博客怎么去写去排版,查了好多相关博客,也根据⾃⼰做过项⽬总结,正好最近搭个微服务框架,顺便把搭建微服务框架所运⽤的知识都进⾏博客梳理,为了以后复习,就仔细琢磨写⼀下⾃⼰在微服务框架中对Dapepr的理解以及项⽬中应⽤。 dapper 只是⼀个代码⽂件,完全开源,你可以在项⽬⾥任何位置,来实现数据到对象ORM操作(当然先引⽤Dapper⽂件),体积⼩速度快。使⽤好处增删改查⽐较快,不⽤⾃⼰写sql,因为这都是重复技术含量低的⼯作,还有程序中⼤量的数据库中读取数据然后创建model,并且为model字段赋值,这都是很轻松的,个⼈认为Dapper可以看做HelpSQL,甚⾄⽐HelperSQL性能⾼⼀点。如果你喜欢原⽣的SQL,那么有喜欢ORM的简单,那你⼀定钟情于Dapper 并且爱上他。
Dapper的优势:
1、Dapper是⼀个轻量级ORM类,代码就是⼀个SQLMapper.cs⽂件,编译后⼀般在40k左右的dll;
2、Dapper快,为啥说快呢?因为Dapepr速度接近IDataReader,取列表的数据超过DataTable;
3、Dapper⽀持什么数据库?⽀持Mysql,sqlLite,SQLServer,Oracle等⼀系列数据库,(备注:我个⼈在在做demo中,就是使⽤了Mysql,SQLServer,公司和个电脑装的数据库不⼀样,就都测试了);
4、Dapper的R⽀持多表并联的对象,⽀持⼀对多,多对多关系,并且没侵⼊性,想⽤就⽤;
5、Dapper原理就是通过Emit反射IDateReader的队列,来快速得到和产⽣对象;这也是性能⾼的原因之⼀;
6、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 = 1)
{
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 > 1000 ? ">" : string.Empty) + "\n"); // 可以记录操作
本文标签:数据 封装 事务 对象 发现 业务 操作
return restult;
}
}
public static int Execute(CommandDefinition command, int databaseOption = 1)
{
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[0]);
return result >= 1;七大古都是哪七个
#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 >= 1;
#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 = 1, 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());
}
finallyqq视频录像
{
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 = 0; i < 100; 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,@AddTim {
ID = Guid.NewGuid(),
EID = Guid.NewGuid(),
Name = "部门",
Remarks = "",
Description = "",
AddTime = DateTime.Now,
IsDel = 0,
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 = 0,
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 ⽂章,请原谅博主成为⼀个⽆耻的⽂档搬运⼯!
⼩弟刚迈⼊博客编写,⽂中如有不对,欢迎⽤板砖扶正,希望给你有所帮助。
本文发布于:2024-11-20 02:33:06,感谢您对本站的认可!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
- 上一篇: 如何在电话中与客户建立起信任关系
- 下一篇: 实现校本课程特发展
发布评论