前言

转眼已经过了金九,光阴真的是似箭啊,周六日常加班,忙里抽闲就想鼓捣个啥看看,刚好最近想着有没有必要换个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包FreeSqlsqlSugarCore,先来个实体吧。

这里注意下,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的更多相关文章

  1. c# 国内外ORM 框架 dapper efcore sqlsugar freesql hisql sqlserver数据常规插入测试性能对比

    c# 国内外ORM 框架 dapper efcore sqlsugar freesql hisql sqlserver数据常规插入测试性能对比对比 在6.22 号发布了 c# sqlsugar,his ...

  2. c# sqlsugar,hisql,freesql orm框架全方位性能测试对比 sqlserver 性能测试

    在2022年1月份本人做过一次sqlsugar,hisql,freesql三个框架的性能测试,上次主要是测的sqlserver下的常规插入(非bulkcopy的方式数据插入),hisql与目前比较流行 ...

  3. Net/NetCore/.NET5 ORM 六大查询体系 - SqlSugar 高级篇

    框架介绍 SqlSugar ORM是一款老牌国产ORM框架,生命力也比较顽强,从早期ORM不成熟阶段,一直存活到现在,我为什么要一直坚持,那是因为还有很多用户在使用,本来我能够较早推出新开源框架 ,可 ...

  4. NET5 ORM 六大新功能 - SqlSugar 5.0.2.7

    介绍 SqlSugar是一款 老牌 .NET 开源ORM框架,并且在第一时间兼容.NET5,由果糖大数据科技团队维护和更新 ,Github star数仅次于EF 和 Dapper 优点: 简单易用.功 ...

  5. ORM 创新解放劳动力 -SqlSugar 新功能介绍

    介绍 SqlSugar是一款 老牌 .NET 开源ORM框架,由果糖大数据科技团队维护和更新 ,Github star数仅次于EF 和 Dapper 优点: 简单易用.功能齐全.高性能.轻量级.服务齐 ...

  6. ORM增删改查并发性能测试

    这两天在对一些ORM进行性能测试(涉及SqlSugar.FreeSql.Fast.Framework.Dapper.LiteSql),测试用的是Winform程序,别人第一眼看到我的程序,说,你这测试 ...

  7. ORM增删改查并发性能测试2

    前言 上一篇<ORM增删改查并发性能测试>出现了点小失误,有的输出SQL日志的代码没有禁用,数据库连接字符串可能有问题.统一环境,统一代码后,重新写一篇. 这次重点是并发性能测试,真不是为 ...

  8. sqlsugar freesql hisql 三个ORM框架性能测试对比

    hisql与目前比较流行的ORM框架性能测试对比 总体测试结果 插入记录数 hisql(耗时) sqlsugar(耗时) freesql(耗时) 5条 0.0107秒 0.0312秒 0.02675秒 ...

  9. hisql 与sqlsugar,freesql 数据插入性能测试

    hisql与目前比较流行的ORM框架性能测试对比 hisql 一直定位为新一代的ORM框架 为低代码开发而生 测试数据数据库为sqlserver数据库 测试源码地址hisql与sqlsugar fre ...

随机推荐

  1. 实体类转xml

    看项目中需要实体类转xml,大家是拼接的.感觉可以利用反射实现.于是写了下 代码如下 package com.kevin.util; import org.springframework.util.O ...

  2. python 03 常用操作符

    1. e记法,科学计数法. AeB   A,B为整数,A*10的B次方. 2. 逻辑运算,真为1,假为0,最好不使用这个计算 true(1)    false(0) true+true=2 3.类型转 ...

  3. NumPy笔记-ndarray

    ndarray,N维数组对象(矩阵) 所有元素必须是相同类型 ndim属性,维度个数 shape属性,各维度大小 dtype属性,数据类型 创建ndarray np.array(collection) ...

  4. 微信小程序自动化

    解析微信小程序 注意:若上面方法不行就使用下面的 小程序对应的chrome驱动版本包,2.4版本的

  5. 03 . Go开发一个日志平台之Elasticsearch使用及kafka消费消息发送到Elasticsearch

    Elasticsearch使用 详细使用请看我写的Go操作Elasticsearch专篇 https://www.cnblogs.com/you-men/p/13391265.html example ...

  6. 【Docker】Docker安装运行dubbo-admin

    运行dubbo-admin服务, 此服务需要单独启动一个zookeeper容器 dubbo-admin将监听所有注册到zookeeper的服务, dubbo-admin默认端口8080 1 运行一个z ...

  7. Unity3d启动事件 - InitializeOnLoad

    监听Unity3d启动事件 - InitializeOnLoad http://blog.csdn.net/huutu/article/details/42318499 Unity 监听第一次进入播放 ...

  8. 使用kubernetes-event-exporter将k8s的事件导出到elasticsearch日志系统中

    使用kubernetes-event-exporter将k8s的事件导出到elasticsearch日志系统中 前提 版本 kubernetes v1.17.9 kubernetes-event-ex ...

  9. Redis Linux 安装部署

    Redis部署文档   Redis部署文档 准备软件: 开始部署: 解压tar包[root@localhost redis]# tar -zxvf redis-3.2.8.tar.gz 进入Redis ...

  10. FastJSON解析JSON的时候保证深堆的顺序

    普通的JSONObject.parseObject(),解析的时候,底层采用HashMap解析所以是无序的, JSONObject params = JSONObject.parseObject(ex ...