关于orm的个人测试——SqlSugar与FreeSql
前言
转眼已经过了金九,光阴真的是似箭啊,周六日常加班,忙里抽闲就想鼓捣个啥看看,刚好最近想着有没有必要换个orm,从当时原生到Dapper,又到现在的Sqlsugar,因为经常听到几个不错的orm,就是今天想测试的Freesql,其实对于造轮子这种事,个人觉得其实是件好事,只有轮子多了,才会有车,虽然参差不齐,但开车的心情还是挺嗨皮的,就算磕磕绊绊,那也是体验过才知道,当然毕竟是开源的自己也可以扩展改造嘛。
开始
因为电脑上只有mysql,这里就单对mysql做下对比测试了,针对增删改查这些常规操作看下性能对比(这里暂时只对sqlsugar与freesql对比,至于其他的,可以加可以加)。
测试环境
- net core 3.1
- FreeSql 1.8.1
- sqlSugarCore 5.0.0.15
- mysql 5.5.53(wc,这么低)
准备工作
新建个控制台工程,引入两个nuget包FreeSql,sqlSugarCore,先来个实体吧。
这里注意下,freesql这个库没有对应的扩展包,例如mysql还需要引入FreeSql.Provider.MySql,具体可看对应文档
[Table(Name = "student_free")]
[SugarTable("student_sugar")]
public class StudentEntity
{
[Column(IsIdentity = true, IsPrimary = true)]
[SugarColumn(IsIdentity = true,IsPrimaryKey = true)]
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Number { get; set; }
public int Sex { get; set; }
public string Location { get; set; }
[Column(Name = "class_id")]
[SugarColumn(ColumnName = "class_id")]
public int ClassID { get; set; }
}
接下来对应实现两个类库的方法类。
freesql
public class FreeSqlUtil
{
private static readonly string CONNECTION_STRING = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root; Initial Catalog=test;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20";
private static IFreeSql _fsql;
private static readonly object locker = new object();
public static IFreeSql GetInstance()
{
if (_fsql == null)
{
lock (locker)
{
if (_fsql == null)
{
_fsql = new FreeSqlBuilder()
.UseConnectionString(DataType.MySql, CONNECTION_STRING)
// .UseAutoSyncStructure(true)
.UseLazyLoading(true)
.Build();
}
}
}
return _fsql;
}
}
当然这里的sql连接串记得替换成自己的。
public class FreeSqlTest
{
public static List<StudentEntity> GetList(int index, int limit)
{
return FreeSqlUtil.GetInstance()
.Select<StudentEntity>()
.Page(index, limit)
.ToList();
}
public static List<StudentEntity> GetList(int limit)
{
return FreeSqlUtil.GetInstance()
.Select<StudentEntity>()
.Limit(limit)
.ToList();
}
public static long Insert(StudentEntity entity)
{
long result = FreeSqlUtil.GetInstance()
.Insert(entity)
.ExecuteIdentity();
return result;
}
public static void InsertList(IEnumerable<StudentEntity> entities)
{
FreeSqlUtil.GetInstance()
.Insert(entities)
.ExecuteAffrows();
}
public static bool Update(StudentEntity entity)
{
int result = FreeSqlUtil.GetInstance()
.Update<StudentEntity>()
.SetSource(entity)
.ExecuteAffrows();
return result > 0;
}
public static void UpdateList(IEnumerable<StudentEntity> entities)
{
FreeSqlUtil.GetInstance()
.Update<StudentEntity>()
.SetSource(entities)
.ExecuteAffrows();
}
}
sqlsugar
这里可以参考我之前文章中专门介绍sqlsugar时整理的util,当然也可以参考我的demo工程April.WebApi
public class BaseDbContext
{
public SqlSugarClient Db;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="connStr">数据库连接串</param>
/// <param name="sqlType">数据库类型</param>
public BaseDbContext(string connStr, int sqlType = 1)
{
InitDataBase(connStr, sqlType);
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="serverIp">服务器IP</param>
/// <param name="user">用户名</param>
/// <param name="pass">密码</param>
/// <param name="dataBase">数据库</param>
public BaseDbContext(string serverIp, string user, string pass, string dataBase)
{
string connStr = $"server={serverIp};user id={user};password={pass};persistsecurityinfo=True;database={dataBase}";
InitDataBase(connStr);
}
/// <summary>
/// 初始化数据库连接
/// </summary>
/// <param name="listConn">连接字符串</param>
private void InitDataBase(string connStr, int sqlType = 1)
{
Db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = connStr,
DbType = (DbType)sqlType,
IsAutoCloseConnection = true,
//SlaveConnectionConfigs = slaveConnectionConfigs
});
Db.Ado.CommandTimeOut = 30000;//设置超时时间
Db.Aop.OnLogExecuted = (sql, pars) => //SQL执行完事件
{
//这里可以查看执行的sql语句跟参数
};
Db.Aop.OnLogExecuting = (sql, pars) => //SQL执行前事件
{
//这里可以查看执行的sql语句跟参数
};
Db.Aop.OnError = (exp) =>//执行SQL 错误事件
{
//这里可以查看执行的sql语句跟参数
};
Db.Aop.OnExecutingChangeSql = (sql, pars) => //SQL执行前 可以修改SQL
{
return new KeyValuePair<string, SugarParameter[]>(sql, pars);
};
}
/// <summary>
/// 开启事务
/// </summary>
public void BeginTran()
{
Db.Ado.BeginTran();
}
/// <summary>
/// 提交事务
/// </summary>
public void CommitTran()
{
Db.Ado.CommitTran();
}
/// <summary>
/// 回滚事务
/// </summary>
public void RollbackTran()
{
Db.Ado.RollbackTran();
}
}
下面是对应的测试方法实现,其中强调一点,对于mysql中有个max_allow_packet这个配置,批量操作的时候会抛出这个异常,当然这里可以通过修改mysql的配置,不过个人建议还是尽可能通过拆解分次,应该也没有动不动甩个万八数据吧(有了轻喷),所以这里调整了插入方法的实现。
public class SqlSugarTest
{
private static readonly string CONNECTION_STRING = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root; Initial Catalog=test;Charset=utf8;SslMode=none;Min Pool Size=20;Max Pool Size=20";
private static BaseDbContext baseDb;
private static SqlSugarClient db;
static SqlSugarTest()
{
baseDb = new BaseDbContext(CONNECTION_STRING, 0);
db = baseDb.Db;
}
public static List<StudentEntity> GetList(int index,int limit)
{
return db.Queryable<StudentEntity>().ToPageList(index, limit);
}
public static List<StudentEntity> GetList(int limit)
{
return db.Queryable<StudentEntity>().Take(limit).ToList();
}
public static int Insert(StudentEntity entity)
{
int result = db.Insertable(entity).ExecuteReturnIdentity();
return result;
}
public static void InsertList(IEnumerable<StudentEntity> entities)
{
if (entities.Count() >= 10000)
{
int count = entities.Count();
int index = 0;
Console.WriteLine($"批量插入{count}数据");
while (count / 5000 > 0)
{
var data = entities.Skip(5000 * index).Take(5000);
db.Insertable(data.ToArray())
.ExecuteCommand();
count -= 5000;
index++;
}
if (count % 5000 > 0)
{
var data = entities.Skip(5000 * index).Take(5000);
db.Insertable(data.ToArray())
.ExecuteCommand();
index++;
}
Console.WriteLine($"拆解执行{index}次");
}
else
{
db.Insertable(entities.ToArray())
.ExecuteCommand();
}
}
public static bool Update(StudentEntity entity)
{
int result = db.Updateable(entity).ExecuteCommand();
return result > 0;
}
public static void UpdateList(IEnumerable<StudentEntity> entities)
{
if (entities.Count() >= 10000)
{
int count = entities.Count();
int index = 0;
Console.WriteLine($"批量修改{count}数据");
while (count / 5000 > 0)
{
var data = entities.Skip(5000 * index).Take(5000);
db.Updateable(data.ToArray())
.ExecuteCommand();
count -= 5000;
index++;
}
if (count % 5000 > 0)
{
var data = entities.Skip(5000 * index).Take(5000);
db.Updateable(data.ToArray())
.ExecuteCommand();
index++;
}
Console.WriteLine($"拆解执行{index}次");
}
else
{
db.Updateable(entities.ToArray())
.ExecuteCommand();
}
}
}
开始测试
测试部分的代码就没啥发的,一个图。

新增(下面有补充)
新增总共测试3次吧,基本时间都是保持一个稳定的。



查询(下面有补充)
查询这里用的是分页方法,库里数据就是单次执行插入测试的数据,总共163006条。


修改(下面有补充)



补充测试
看了下freesql入门文章,发现配置这块儿这样写,不使用命令参数化,在新增和修改的速度就很明显了,当然实际使用的时候还是要注意,毕竟注入还是可怕的。

新增

查询

修改

小结
虽然不知道这个测试结果有没有什么问题(毕竟没咋用过),不过通过时间上来看 ,FreeSql在速度上确实是有优势,当然这里只是基础的方法测试,没有什么各种功能的尝试,不过毕竟常用的还是增删改查嘛,再鼓捣什么demo的时候可以考虑下尝试freesql了,虽然目前看来对于现工程的改动还不是太迫切,也希望轮子越来越多,越来越好,当然自己没事也会继续鼓捣,学无止境,路漫漫。
关于orm的个人测试——SqlSugar与FreeSql的更多相关文章
- c# 国内外ORM 框架 dapper efcore sqlsugar freesql hisql sqlserver数据常规插入测试性能对比
c# 国内外ORM 框架 dapper efcore sqlsugar freesql hisql sqlserver数据常规插入测试性能对比对比 在6.22 号发布了 c# sqlsugar,his ...
- c# sqlsugar,hisql,freesql orm框架全方位性能测试对比 sqlserver 性能测试
在2022年1月份本人做过一次sqlsugar,hisql,freesql三个框架的性能测试,上次主要是测的sqlserver下的常规插入(非bulkcopy的方式数据插入),hisql与目前比较流行 ...
- Net/NetCore/.NET5 ORM 六大查询体系 - SqlSugar 高级篇
框架介绍 SqlSugar ORM是一款老牌国产ORM框架,生命力也比较顽强,从早期ORM不成熟阶段,一直存活到现在,我为什么要一直坚持,那是因为还有很多用户在使用,本来我能够较早推出新开源框架 ,可 ...
- NET5 ORM 六大新功能 - SqlSugar 5.0.2.7
介绍 SqlSugar是一款 老牌 .NET 开源ORM框架,并且在第一时间兼容.NET5,由果糖大数据科技团队维护和更新 ,Github star数仅次于EF 和 Dapper 优点: 简单易用.功 ...
- ORM 创新解放劳动力 -SqlSugar 新功能介绍
介绍 SqlSugar是一款 老牌 .NET 开源ORM框架,由果糖大数据科技团队维护和更新 ,Github star数仅次于EF 和 Dapper 优点: 简单易用.功能齐全.高性能.轻量级.服务齐 ...
- ORM增删改查并发性能测试
这两天在对一些ORM进行性能测试(涉及SqlSugar.FreeSql.Fast.Framework.Dapper.LiteSql),测试用的是Winform程序,别人第一眼看到我的程序,说,你这测试 ...
- ORM增删改查并发性能测试2
前言 上一篇<ORM增删改查并发性能测试>出现了点小失误,有的输出SQL日志的代码没有禁用,数据库连接字符串可能有问题.统一环境,统一代码后,重新写一篇. 这次重点是并发性能测试,真不是为 ...
- sqlsugar freesql hisql 三个ORM框架性能测试对比
hisql与目前比较流行的ORM框架性能测试对比 总体测试结果 插入记录数 hisql(耗时) sqlsugar(耗时) freesql(耗时) 5条 0.0107秒 0.0312秒 0.02675秒 ...
- hisql 与sqlsugar,freesql 数据插入性能测试
hisql与目前比较流行的ORM框架性能测试对比 hisql 一直定位为新一代的ORM框架 为低代码开发而生 测试数据数据库为sqlserver数据库 测试源码地址hisql与sqlsugar fre ...
随机推荐
- linux驱动之定时器的介绍和内核时间的学习
本文章摘自下面的网友: http://blog.sina.com.cn/s/blog_6e5b342e0100m87d.html 一.内核中如何记录时间 任何程序都需要时间控制,其主要目的是: 测量时 ...
- JavaScript学习系列博客_12_JavaScript中的break、continue关键字
break关键字 -break关键字可以用来退出switch或循环语句 -不能在if语句中使用break和continue,但不是说if语句里面不能写break关键字,break关键字一定要包含在sw ...
- 逆流而上,7月阿里最新出炉的三面面经,年薪50W,我行您也行
从7月份开始,打算找工作,一个偶然的机会,拉勾上一个蚂蚁金服的师兄找到我,说要内推,在此感谢姚师兄,然后就开始了蚂蚁金服的面试之旅.把简历发过去之后,就收到了邮件通知,10个工作日联系我,请耐心等待. ...
- Java数据结构——AVL树
AVL树(平衡二叉树)定义 AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树,并且拥有自平衡机制.在AV ...
- Linux操作命令和工具使用
lrzsz是一个unix通信套件提供的X,Y,和ZModem文件传输协议. windows 需要向centos服务器上传文件,可直接在centos上执行命令yum -y install lrzsz 程 ...
- “路由大当家”OSPF的小秘密
引入 OPSF是应用最广的路由协议,基本上,所有的IGP用到的都是OSPF,下面我们看看它的“小秘密” 优点: •没有跳数限制 •使用组播更新变化的路由和网络信息 •路由收敛速度较快 •以开销(Cos ...
- RabbitMQ配置文件(rabbitmq.conf)
rabbitmq.conf配置文件示例: #====================================== #RabbitMQ经纪人部分 #======================= ...
- 拾色器,可以取出电脑屏幕的任何颜色,ui以及程序员前端等常用软件,文件很小,300K
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985,转载请说明出处. 今天给大家介绍一个小软件,挺实用的,叫做拾色器. 用途:取出电脑屏幕的任意颜色,当你 ...
- unity webview
uniwebview http://uniwebview.onevcat.com/manual Unity3D研究院之在Android中打开WebView(三十) http://www.xuanyus ...
- 跨平台C# UI库
https://github.com/AvaloniaUI/Avalonia https://www.cnblogs.com/leolion/p/7144896.html https://github ...