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

打印 上一主题 下一主题

主题 863|帖子 863|积分 2589

前言

上一篇《ORM增删改查并发性能测试》出现了点小失误,有的输出SQL日志的代码没有禁用,数据库连接字符串可能有问题。统一环境,统一代码后,重新写一篇。
这次重点是并发性能测试,真不是为了diss其它ORM,开始是因为我写的Dapper.LiteSql高并发场景下存在BUG,才写了这个测试,经过修改优化,最好Dapper.LiteSql通过了这个测试。然后Fast.Framework的作者说他的ORM性能很好,我就好奇,是否真的有他说的这么好,口说无凭,我就对它进程各种测试,包括这个高并发测试,刚开始Fast.Framework高并发测试也不通过,后经过作者的优化,就通过了。
本测试不偏向任何ORM,有一说一。如果测试环境或程序有问题,请指出,难免有失误。
测试的现实意义

这两天在对一些ORM进行性能测试(涉及SqlSugar、FreeSql、Fast.Framework、Dapper.LiteSql),测试用的是Winform程序,别人第一眼看到我的程序,说,你这测试没意义!
可能我的测试程序的某些地方写的比较变态吧,但我认为有现实意义,并且网上有相关网站崩溃问题的文章,那什么“爆高分析”,“崩溃问题”,WinDbg用的很6,那写程序阶段为什么没发现呢?
场景

假设WebApi(或者说网站后台服务)正在被高并发访问,一段时间后,服务的线程数量达到了200正常的是类似这样的,任务来了,就干活:及以上,那么.NET的线程池,如果线程处于空闲状态,默认是20秒后释放线程,假设这200多个线程空闲了,但是还没有达到空闲20秒的时间,还没有释放,如果此时,又有大量高并发的访问,200个线程去操作数据库,那就可能很危险了。
关于性能

虽然代码写的可能有点变态,但我的测试不是很严格,也不是很规范。
性能如果不是数量级的差,问题都不大,比如一个是0.8秒,一个是1.8秒,那1.8秒的慢是慢了一点,但问题不大;但如果一个是0.8秒,一个是10秒,那10秒的这个,可能就有点问题了,即使别人用的Emit你用的反射,也不应该差这么多。
当然了,我的测试,数据规模不大,10000条,button可能会点10次,那也才10万数据量,在数据量方面我没有做极端测试,我的重点不是这个,因为很少会去查100万数据到内存中,就暂不讨论这个。
这个测试除了大体上测试一下性能,主要就是增加了并发测试。
非并发性能测试的截图我就不放全了,这几个ORM有差别,但我觉得2秒3秒还是6秒甚至8秒,都问题不大的,都算差不多,都算堪用。
测试环境

数据库及设置

测试数据库是MySQL,版本5.7.28
MySql的连接池大小是1200

测试程序中配置的数据连接字符串
  1. Data Source=localhost;Port=3306;User ID=root;Password=123456;Initial Catalog=xxxxxx_test;Charset=utf8mb4;SslMode=none;Allow User Variables=True;
复制代码
MySql.Data.dll版本

MySql.Data.dll目前用的是最新的8.0.30版本(题外话,它里面的异步是假异步,把同步方法包装成的异步,我说怎么反而慢了呢,真异步要使用MySqlConnector.dll,Fast.Framework使用的是这个性能很好)。
参数化

测试的增删改查,都是参数化的。
实体类

以SqlSugar的为例吧,几种ORM测试用的表结构是相同的。
  1. using System;
  2. using System.Linq;
  3. using System.Text;
  4. using SqlSugar;
  5. namespace Models
  6. {
  7.     ///<summary>
  8.     ///用户表
  9.     ///</summary>
  10.     [SugarTable("sys_user")]
  11.     public partial class SysUser
  12.     {
  13.            public SysUser(){
  14.            }
  15.            /// <summary>
  16.            /// Desc:主键
  17.            /// Default:
  18.            /// Nullable:False
  19.            /// </summary>           
  20.            [SugarColumn(IsPrimaryKey=true,IsIdentity=true,ColumnName="id")]
  21.            public long Id {get;set;}
  22.            /// <summary>
  23.            /// Desc:用户名
  24.            /// Default:
  25.            /// Nullable:False
  26.            /// </summary>           
  27.            [SugarColumn(ColumnName="user_name")]
  28.            public string UserName {get;set;}
  29.            /// <summary>
  30.            /// Desc:用户姓名
  31.            /// Default:
  32.            /// Nullable:True
  33.            /// </summary>           
  34.            [SugarColumn(ColumnName="real_name")]
  35.            public string RealName {get;set;}
  36.            /// <summary>
  37.            /// Desc:用户密码
  38.            /// Default:
  39.            /// Nullable:False
  40.            /// </summary>           
  41.            [SugarColumn(ColumnName="password")]
  42.            public string Password {get;set;}
  43.            /// <summary>
  44.            /// Desc:备注
  45.            /// Default:
  46.            /// Nullable:True
  47.            /// </summary>           
  48.            [SugarColumn(ColumnName="remark")]
  49.            public string Remark {get;set;}
  50.            /// <summary>
  51.            /// Desc:创建者ID
  52.            /// Default:
  53.            /// Nullable:False
  54.            /// </summary>           
  55.            [SugarColumn(ColumnName="create_userid")]
  56.            public string CreateUserid {get;set;}
  57.            /// <summary>
  58.            /// Desc:创建时间
  59.            /// Default:
  60.            /// Nullable:False
  61.            /// </summary>           
  62.            [SugarColumn(ColumnName="create_time")]
  63.            public DateTime CreateTime {get;set;}
  64.            /// <summary>
  65.            /// Desc:更新者ID
  66.            /// Default:
  67.            /// Nullable:True
  68.            /// </summary>           
  69.            [SugarColumn(ColumnName="update_userid")]
  70.            public string UpdateUserid {get;set;}
  71.            /// <summary>
  72.            /// Desc:更新时间
  73.            /// Default:
  74.            /// Nullable:True
  75.            /// </summary>           
  76.            [SugarColumn(ColumnName="update_time")]
  77.            public DateTime? UpdateTime {get;set;}
  78.     }
  79. }
复制代码
测试配置及代码

Dapper.LiteSql net461
  1. public class LiteSqlFactory
  2. {
  3.     #region 变量
  4.     private static ILiteSqlClient _liteSqlClient = new LiteSqlClient("Data Source=localhost;Port=3306;User ID=root;Password=123456;Initial Catalog=litesql_test;Charset=utf8mb4;SslMode=none;Allow User Variables=True;", DBType.MySQL, new MySQLProvider());
  5.     #endregion
  6.     #region 获取 ISession
  7.     /// <summary>
  8.     /// 获取 ISession
  9.     /// </summary>
  10.     /// <param name="splitTableMapping">分表映射</param>
  11.     public static ISession GetSession(SplitTableMapping splitTableMapping = null)
  12.     {
  13.         return _liteSqlClient.GetSession(splitTableMapping);
  14.     }
  15.     #endregion
  16.     #region 获取 ISession (异步)
  17.     /// <summary>
  18.     /// 获取 ISession (异步)
  19.     /// </summary>
  20.     /// <param name="splitTableMapping">分表映射</param>
  21.     public static async Task<ISession> GetSessionAsync(SplitTableMapping splitTableMapping = null)
  22.     {
  23.         return await _liteSqlClient.GetSessionAsync(splitTableMapping);
  24.     }
  25.     #endregion
  26. }
复制代码
  1. using DAL;
  2. using Dapper.LiteSql;
  3. using Models;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.ComponentModel;
  7. using System.Data;
  8. using System.Drawing;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. using System.Windows.Forms;
  14. using Utils;
  15. namespace PerformanceTest
  16. {
  17.     public partial class Form1 : Form
  18.     {
  19.         #region 变量
  20.         private BsOrderDal m_BsOrderDal = ServiceHelper.Get<BsOrderDal>();
  21.         private SysUserDal m_SysUserDal = ServiceHelper.Get<SysUserDal>();
  22.         private Random _rnd = new Random();
  23.         private int _count = 10000;
  24.         private bool _printSql = false;
  25.         #endregion
  26.         #region Form1
  27.         public Form1()
  28.         {
  29.             InitializeComponent();
  30.         }
  31.         #endregion
  32.         #region Form1_Load
  33.         private void Form1_Load(object sender, EventArgs e)
  34.         {
  35.             RunTask(() =>
  36.             {
  37.                 LiteSqlFactory.GetSession();  //预热
  38.                 Log("预热完成");
  39.             });
  40.         }
  41.         #endregion
  42.         #region Log
  43.         private void Log(string log)
  44.         {
  45.             if (!this.IsDisposed)
  46.             {
  47.                 string msg = DateTime.Now.ToString("mm:ss.fff") + " " + log + "\r\n\r\n";
  48.                 if (this.InvokeRequired)
  49.                 {
  50.                     this.BeginInvoke(new Action(() =>
  51.                     {
  52.                         textBox1.AppendText(msg);
  53.                     }));
  54.                 }
  55.                 else
  56.                 {
  57.                     textBox1.AppendText(msg);
  58.                 }
  59.             }
  60.         }
  61.         #endregion
  62.         #region 清空输出框
  63.         private void button10_Click(object sender, EventArgs e)
  64.         {
  65.             textBox1.Text = string.Empty;
  66.         }
  67.         #endregion
  68.         #region RunTask
  69.         private Task RunTask(Action action)
  70.         {
  71.             return Task.Run(() =>
  72.             {
  73.                 try
  74.                 {
  75.                     action();
  76.                 }
  77.                 catch (Exception ex)
  78.                 {
  79.                     Log(ex.ToString());
  80.                     throw;
  81.                 }
  82.             });
  83.         }
  84.         private Task RunTask<T>(Action<T> action, T t)
  85.         {
  86.             return Task.Factory.StartNew(obj =>
  87.             {
  88.                 try
  89.                 {
  90.                     action((T)obj);
  91.                 }
  92.                 catch (Exception ex)
  93.                 {
  94.                     Log(ex.ToString());
  95.                     throw;
  96.                 }
  97.             }, t);
  98.         }
  99.         #endregion
  100.         #region cbxPrintSql_Click
  101.         private void cbxPrintSql_Click(object sender, EventArgs e)
  102.         {
  103.             _printSql = cbxPrintSql.Checked;
  104.         }
  105.         #endregion
  106.         #region 删除
  107.         private void button5_Click(object sender, EventArgs e)
  108.         {
  109.             RunTask(() =>
  110.             {
  111.                 Log("删除 开始");
  112.                 var session = LiteSqlFactory.GetSession();
  113.                 session.CreateSql("id>@Id", 12).DeleteByCondition<SysUser>();
  114.                 Log("删除 完成");
  115.             });
  116.         }
  117.         #endregion
  118.         #region 测试批量修改
  119.         private void button3_Click(object sender, EventArgs e)
  120.         {
  121.             RunTask(() =>
  122.             {
  123.                 List<SysUser> userList = m_SysUserDal.GetList("select t.* from sys_user t where t.id > 20");
  124.                 Log("批量修改 开始 count=" + userList.Count);
  125.                 DateTime dt = DateTime.Now;
  126.                 var session = LiteSqlFactory.GetSession();
  127.                 if (_printSql)
  128.                 {
  129.                     session.OnExecuting = (s, p) => Console.WriteLine(s); //打印SQL
  130.                 }
  131.                 try
  132.                 {
  133.                     session.AttachOld(userList);
  134.                     foreach (SysUser user in userList)
  135.                     {
  136.                         user.Remark = "测试修改用户" + _rnd.Next(1, 10000);
  137.                         user.UpdateUserid = "1";
  138.                         user.UpdateTime = DateTime.Now;
  139.                     }
  140.                     userList.ForEach(item => item.UpdateTime = DateTime.Now);
  141.                     session.BeginTransaction();
  142.                     session.Update(userList);
  143.                     session.CommitTransaction();
  144.                 }
  145.                 catch (Exception ex)
  146.                 {
  147.                     session.RollbackTransaction();
  148.                     throw;
  149.                 }
  150.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  151.                 Log("批量修改 完成,耗时:" + time + "秒");
  152.             });
  153.         }
  154.         #endregion
  155.         #region 测试批量添加
  156.         private void button4_Click(object sender, EventArgs e)
  157.         {
  158.             RunTask(() =>
  159.             {
  160.                 List<SysUser> userList = new List<SysUser>();
  161.                 for (int i = 1; i <= _count; i++)
  162.                 {
  163.                     SysUser user = new SysUser();
  164.                     user.UserName = "testUser";
  165.                     user.RealName = "测试插入用户";
  166.                     user.Password = "123456";
  167.                     user.CreateUserid = "1";
  168.                     user.CreateTime = DateTime.Now;
  169.                     userList.Add(user);
  170.                 }
  171.                 Log("批量添加 开始 count=" + userList.Count);
  172.                 DateTime dt = DateTime.Now;
  173.                 var session = LiteSqlFactory.GetSession();
  174.                 if (_printSql)
  175.                 {
  176.                     session.OnExecuting = (s, p) => Console.WriteLine(s); //打印SQL
  177.                 }
  178.                 try
  179.                 {
  180.                     session.BeginTransaction();
  181.                     session.Insert(userList);
  182.                     session.CommitTransaction();
  183.                 }
  184.                 catch
  185.                 {
  186.                     session.RollbackTransaction();
  187.                     throw;
  188.                 }
  189.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  190.                 Log("批量添加 完成,耗时:" + time + "秒");
  191.             });
  192.         }
  193.         #endregion
  194.         #region 测试循环修改
  195.         private void button7_Click(object sender, EventArgs e)
  196.         {
  197.             RunTask(() =>
  198.             {
  199.                 List<SysUser> userList = m_SysUserDal.GetList("select t.* from sys_user t where t.id > 20");
  200.                 Log("循环修改 开始 count=" + userList.Count);
  201.                 DateTime dt = DateTime.Now;
  202.                 var session = LiteSqlFactory.GetSession();
  203.                 if (_printSql)
  204.                 {
  205.                     session.OnExecuting = (s, p) => Console.WriteLine(s); //打印SQL
  206.                 }
  207.                 try
  208.                 {
  209.                     session.AttachOld(userList);
  210.                     foreach (SysUser user in userList)
  211.                     {
  212.                         user.Remark = "测试修改用户" + _rnd.Next(1, 10000);
  213.                         user.UpdateUserid = "1";
  214.                         user.UpdateTime = DateTime.Now;
  215.                     }
  216.                     session.BeginTransaction();
  217.                     foreach (SysUser user in userList)
  218.                     {
  219.                         session.Update(user);
  220.                     }
  221.                     session.CommitTransaction();
  222.                 }
  223.                 catch
  224.                 {
  225.                     session.RollbackTransaction();
  226.                     throw;
  227.                 }
  228.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  229.                 Log("循环修改 完成,耗时:" + time + "秒");
  230.             });
  231.         }
  232.         #endregion
  233.         #region 测试循环添加
  234.         private void button6_Click(object sender, EventArgs e)
  235.         {
  236.             RunTask(() =>
  237.             {
  238.                 List<SysUser> userList = new List<SysUser>();
  239.                 for (int i = 1; i <= _count; i++)
  240.                 {
  241.                     SysUser user = new SysUser();
  242.                     user.UserName = "testUser";
  243.                     user.RealName = "测试插入用户";
  244.                     user.Password = "123456";
  245.                     user.CreateUserid = "1";
  246.                     user.CreateTime = DateTime.Now;
  247.                     userList.Add(user);
  248.                 }
  249.                 Log("循环添加 开始 count=" + userList.Count);
  250.                 DateTime dt = DateTime.Now;
  251.                 var session = LiteSqlFactory.GetSession();
  252.                 if (_printSql)
  253.                 {
  254.                     session.OnExecuting = (s, p) => Console.WriteLine(s); //打印SQL
  255.                 }
  256.                 try
  257.                 {
  258.                     session.BeginTransaction();
  259.                     foreach (SysUser user in userList)
  260.                     {
  261.                         session.Insert(user);
  262.                     }
  263.                     session.CommitTransaction();
  264.                 }
  265.                 catch
  266.                 {
  267.                     session.RollbackTransaction();
  268.                     throw;
  269.                 }
  270.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  271.                 Log("循环添加 完成,耗时:" + time + "秒");
  272.             });
  273.         }
  274.         #endregion
  275.         #region 查询
  276.         private void button1_Click(object sender, EventArgs e)
  277.         {
  278.             RunTask(() =>
  279.             {
  280.                 Log("查询 开始");
  281.                 DateTime dt = DateTime.Now;
  282.                 for (int i = 0; i < 10; i++)
  283.                 {
  284.                     var session = LiteSqlFactory.GetSession();
  285.                     ISqlString sql = session.CreateSql(@"
  286.                         select t.*
  287.                         from sys_user t
  288.                         where t.id > @id
  289.                         and t.real_name like @remark", 20, "%测试%");
  290.                     sql.Append(" order by t.create_time desc, t.id asc");
  291.                     List<SysUser> userList = sql.QueryList<SysUser>();
  292.                     Log("查询结果 count=" + userList.Count.ToString());
  293.                 }
  294.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  295.                 Log("查询 完成,耗时:" + time + "秒");
  296.             });
  297.         }
  298.         #endregion
  299.         #region 分页查询
  300.         private void button2_Click(object sender, EventArgs e)
  301.         {
  302.             RunTask(() =>
  303.             {
  304.                 Log("分页查询 开始");
  305.                 DateTime dt = DateTime.Now;
  306.                 for (int i = 0; i < 10; i++)
  307.                 {
  308.                     int total = m_SysUserDal.GetTotalCount();
  309.                     int pageSize = 100;
  310.                     int pageCount = (total - 1) / pageSize + 1;
  311.                     var session = LiteSqlFactory.GetSession();
  312.                     List<SysUser> userList = new List<SysUser>();
  313.                     for (int page = 1; page <= pageCount; page++)
  314.                     {
  315.                         ISqlString sql = session.CreateSql(@"
  316.                             select t.*
  317.                             from sys_user t
  318.                             where 1=1
  319.                             and t.id > @id
  320.                             and t.real_name like @remark", 20, "%测试%");
  321.                         string orderby = " order by t.create_time desc, t.id asc";
  322.                         userList.AddRange(sql.QueryPage<SysUser>(orderby, pageSize, page));
  323.                     }
  324.                     Log("分页查询结果 count=" + userList.Count.ToString());
  325.                 }
  326.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  327.                 Log("分页查询 完成,耗时:" + time + "秒");
  328.             });
  329.         }
  330.         #endregion
  331.         #region 并发查询
  332.         private void button8_Click(object sender, EventArgs e)
  333.         {
  334.             ThreadPool.SetMaxThreads(1000, 1000);
  335.             ThreadPool.SetMinThreads(200, 200);
  336.             RunTask(() =>
  337.             {
  338.                 Log("并发查询 开始");
  339.                 DateTime dt = DateTime.Now;
  340.                 List<Task> tasks = new List<Task>();
  341.                 for (int i = 1; i <= 1000; i++)
  342.                 {
  343.                     int index = i;
  344.                     Task task = RunTask(() =>
  345.                     {
  346.                         var session = LiteSqlFactory.GetSession();
  347.                         ISqlString sql = session.CreateSql(@"
  348.                             select t.*
  349.                             from sys_user t
  350.                             where t.id > @id
  351.                             and t.real_name like @remark", 20, "%测试%");
  352.                         sql.Append(" order by t.create_time desc, t.id asc");
  353.                         List<SysUser> userList = sql.QueryList<SysUser>();
  354.                         if (index % 50 == 0) Log("第" + index + "次查询结果 count=" + userList.Count);
  355.                     });
  356.                     tasks.Add(task);
  357.                 }
  358.                 Task.WaitAll(tasks.ToArray());
  359.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  360.                 Log("并发查询 完成,耗时:" + time + "秒");
  361.             });
  362.         }
  363.         #endregion
  364.         #region 并发插入
  365.         private void button9_Click(object sender, EventArgs e)
  366.         {
  367.             ThreadPool.SetMaxThreads(1000, 1000);
  368.             ThreadPool.SetMinThreads(200, 200);
  369.             RunTask(() =>
  370.             {
  371.                 List<SysUser> userList = new List<SysUser>();
  372.                 for (int i = 1; i <= _count; i++)
  373.                 {
  374.                     SysUser user = new SysUser();
  375.                     user.UserName = "testUser";
  376.                     user.RealName = "测试插入用户";
  377.                     user.Remark = "测试插入用户" + i;
  378.                     user.Password = "123456";
  379.                     user.CreateUserid = "1";
  380.                     user.CreateTime = DateTime.Now;
  381.                     userList.Add(user);
  382.                 }
  383.                 Log("并发插入 开始 count=" + userList.Count);
  384.                 DateTime dt = DateTime.Now;
  385.                 List<Task> tasks = new List<Task>();
  386.                 foreach (SysUser item in userList)
  387.                 {
  388.                     var task = RunTask(user =>
  389.                     {
  390.                         LiteSqlFactory.GetSession().Insert(user);
  391.                     }, item);
  392.                     tasks.Add(task);
  393.                 }
  394.                 Task.WaitAll(tasks.ToArray());
  395.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  396.                 Log("并发插入 完成,耗时:" + time + "秒");
  397.             });
  398.         }
  399.         #endregion
  400.     }
  401. }
复制代码
FreeSql net461

注意:Winform程序能够通过测试,如果是控制台程序,需要把connection timeout设置大一点,才能通过测试。
  1. public class FreeSqlUtil
  2. {
  3.     #region CreateFreeSqlClient
  4.     public static IFreeSql CreateFreeSqlClient()
  5.     {
  6.         IFreeSql db = new FreeSql.FreeSqlBuilder()
  7.             .UseConnectionString(FreeSql.DataType.MySql, @"Data Source=localhost;Port=3306;User ID=root;Password=123456;Initial Catalog=freesql_test;Charset=utf8mb4;SslMode=none;Allow User Variables=True;")
  8.             .UseGenerateCommandParameterWithLambda(true)
  9.             .Build(); //请务必定义成 Singleton 单例模式
  10.         return db;
  11.     }
  12.     #endregion
  13. }
复制代码
  1. using Models;
  2. using NLog;
  3. using FreeSqlDemo.Utils;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.ComponentModel;
  7. using System.Data;
  8. using System.Drawing;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using System.Windows.Forms;
  13. using FreeSql.Aop;
  14. using Newtonsoft.Json;
  15. using System.Threading;
  16. namespace FreeSqlDemo
  17. {
  18.     public partial class Form1 : Form
  19.     {
  20.         #region 变量
  21.         private Logger _log = NLog.LogManager.GetCurrentClassLogger();
  22.         private IFreeSql _db;
  23.         private int _count = 10000;
  24.         private bool _printSql = false;
  25.         #endregion
  26.         #region Form1
  27.         public Form1()
  28.         {
  29.             InitializeComponent();
  30.         }
  31.         #endregion
  32.         #region Form1_Load
  33.         private void Form1_Load(object sender, EventArgs e)
  34.         {
  35.             _db = FreeSqlUtil.CreateFreeSqlClient();
  36.             if (_printSql)
  37.             {
  38.                 _db.Aop.CurdAfter += CurdAfter;
  39.             }
  40.             RunTask(() =>
  41.             {
  42.                 _db.Queryable<SysUser>().Count(); //预热
  43.                 Log("预热完成");
  44.             });
  45.         }
  46.         #endregion
  47.         #region Log
  48.         private void Log(string log)
  49.         {
  50.             if (!this.IsDisposed)
  51.             {
  52.                 string msg = DateTime.Now.ToString("mm:ss.fff") + " " + log + "\r\n\r\n";
  53.                 if (this.InvokeRequired)
  54.                 {
  55.                     this.BeginInvoke(new Action(() =>
  56.                     {
  57.                         textBox1.AppendText(msg);
  58.                     }));
  59.                 }
  60.                 else
  61.                 {
  62.                     textBox1.AppendText(msg);
  63.                 }
  64.             }
  65.         }
  66.         #endregion
  67.         #region 清空输出框
  68.         private void button10_Click(object sender, EventArgs e)
  69.         {
  70.             textBox1.Text = string.Empty;
  71.         }
  72.         #endregion
  73.         #region RunTask
  74.         private Task RunTask(Action action)
  75.         {
  76.             return Task.Run(() =>
  77.             {
  78.                 try
  79.                 {
  80.                     action();
  81.                 }
  82.                 catch (Exception ex)
  83.                 {
  84.                     Log(ex.Message + "\r\n" + ex.StackTrace);
  85.                 }
  86.             });
  87.         }
  88.         private Task RunTask<T>(Action<T> action, T t)
  89.         {
  90.             return Task.Factory.StartNew(obj =>
  91.             {
  92.                 try
  93.                 {
  94.                     action((T)obj);
  95.                 }
  96.                 catch (Exception ex)
  97.                 {
  98.                     Log(ex.ToString());
  99.                     throw;
  100.                 }
  101.             }, t);
  102.         }
  103.         #endregion
  104.         #region 打印SQL
  105.         private void CurdAfter(object sender, CurdAfterEventArgs e)
  106.         {
  107.             if (_printSql)
  108.             {
  109.                 RunTask(() =>
  110.                 {
  111.                     string msg = "SQL:" + e.Sql + "\r\nParam:" + JsonConvert.SerializeObject(e.DbParms.ToDictionary(it => it.ParameterName, it => it.Value));
  112.                     Console.WriteLine(msg);
  113.                     _log.Debug(msg);
  114.                 });
  115.             }
  116.         }
  117.         #endregion
  118.         #region cbxPrintSql_Click
  119.         private void cbxPrintSql_Click(object sender, EventArgs e)
  120.         {
  121.             _printSql = cbxPrintSql.Checked;
  122.         }
  123.         #endregion
  124.         #region 生成实体类
  125.         private void button1_Click(object sender, EventArgs e)
  126.         {
  127.             RunTask(() =>
  128.             {
  129.                 Log("开始生成实体类");
  130.                 Log("生成实体类完成");
  131.             });
  132.         }
  133.         #endregion
  134.         #region 测试查询
  135.         private void button2_Click(object sender, EventArgs e)
  136.         {
  137.             Log("开始查询");
  138.             SysUser conditionModel = new SysUser();
  139.             conditionModel.Remark = "管理员";
  140.             string remark = "管理员";
  141.             List<SysUser> list = _db.Queryable<SysUser>().Where(t => t.Id < 20 && t.Remark.Contains(conditionModel.Remark) && t.CreateTime > new DateTime(2010, 1, 1)).ToList();
  142.             foreach (SysUser user in list)
  143.             {
  144.                 Log(string.Format("{0},{1},{2},{3}", user.UserName, user.RealName, user.Remark, user.CreateTime.ToString("yyyy-MM-dd")));
  145.             }
  146.             Log("查询结束 count=" + list.Count);
  147.         }
  148.         #endregion
  149.         #region 测试批量修改
  150.         private void button3_Click(object sender, EventArgs e)
  151.         {
  152.             RunTask(() =>
  153.             {
  154.                 Random rnd = new Random();
  155.                 List<SysUser> userList = _db.Queryable<SysUser>().Where(t => t.Id > 20).ToList();
  156.                 Log("批量修改 开始 count=" + userList.Count.ToString("0 000"));
  157.                 foreach (SysUser user in userList)
  158.                 {
  159.                     user.Remark = "测试修改用户" + rnd.Next(0, 10000);
  160.                     user.UpdateUserid = "1";
  161.                     user.UpdateTime = DateTime.Now;
  162.                 }
  163.                 DateTime dt = DateTime.Now;
  164.                 _db.Ado.Transaction(() =>
  165.                 {
  166.                     _db.Update<SysUser>().SetSource(userList).ExecuteAffrows();
  167.                 });
  168.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  169.                 Log("批量修改 完成,耗时:" + time + "秒");
  170.             });
  171.         }
  172.         #endregion
  173.         #region 测试批量添加
  174.         private void button4_Click(object sender, EventArgs e)
  175.         {
  176.             RunTask(() =>
  177.             {
  178.                 List<SysUser> userList = new List<SysUser>();
  179.                 for (int i = 1; i <= _count; i++)
  180.                 {
  181.                     SysUser user = new SysUser();
  182.                     user.UserName = "testUser";
  183.                     user.RealName = "测试插入用户";
  184.                     user.Password = "123456";
  185.                     user.CreateUserid = "1";
  186.                     user.CreateTime = DateTime.Now;
  187.                     userList.Add(user);
  188.                 }
  189.                 Log("批量添加 开始 count=" + userList.Count);
  190.                 DateTime dt = DateTime.Now;
  191.                 _db.Ado.Transaction(() =>
  192.                 {
  193.                     _db.Insert(userList).ExecuteAffrows();
  194.                 });
  195.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  196.                 Log("批量添加 结束,完成:" + time + "秒");
  197.             });
  198.         }
  199.         #endregion
  200.         #region 删除
  201.         private void button5_Click(object sender, EventArgs e)
  202.         {
  203.             RunTask(() =>
  204.             {
  205.                 Log("删除 开始");
  206.                 _db.Delete<SysUser>().Where(t => t.Id > 20).ExecuteAffrows();
  207.                 Log("删除 完成");
  208.             });
  209.         }
  210.         #endregion
  211.         #region 测试循环修改
  212.         private void button7_Click(object sender, EventArgs e)
  213.         {
  214.             RunTask(() =>
  215.             {
  216.                 Random rnd = new Random();
  217.                 List<SysUser> userList = _db.Queryable<SysUser>().Where(t => t.Id > 20).ToList();
  218.                 Log("循环修改 开始 count=" + userList.Count.ToString("0 000"));
  219.                 DateTime dt = DateTime.Now;
  220.                 _db.Ado.Transaction(() =>
  221.                 {
  222.                     var repo = _db.GetRepository<SysUser>();
  223.                     foreach (SysUser user in userList)
  224.                     {
  225.                         repo.Attach(user);
  226.                     }
  227.                     foreach (SysUser user in userList)
  228.                     {
  229.                         user.Remark = "测试修改用户" + rnd.Next(0, 10000);
  230.                         user.UpdateUserid = "1";
  231.                         user.UpdateTime = DateTime.Now;
  232.                     }
  233.                     foreach (SysUser user in userList)
  234.                     {
  235.                         repo.Update(user);
  236.                     }
  237.                 });
  238.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  239.                 Log("循环修改 完成,耗时:" + time + "秒");
  240.             });
  241.         }
  242.         #endregion
  243.         #region 测试循环添加
  244.         private void button6_Click(object sender, EventArgs e)
  245.         {
  246.             RunTask(() =>
  247.             {
  248.                 List<SysUser> userList = new List<SysUser>();
  249.                 for (int i = 1; i <= _count; i++)
  250.                 {
  251.                     SysUser user = new SysUser();
  252.                     user.UserName = "testUser";
  253.                     user.RealName = "测试插入用户";
  254.                     user.Password = "123456";
  255.                     user.CreateUserid = "1";
  256.                     user.CreateTime = DateTime.Now;
  257.                     userList.Add(user);
  258.                 }
  259.                 Log("循环添加 开始 count=" + userList.Count);
  260.                 DateTime dt = DateTime.Now;
  261.                 _db.Ado.Transaction(() =>
  262.                 {
  263.                     foreach (SysUser user in userList)
  264.                     {
  265.                         _db.Insert(user).ExecuteIdentity();
  266.                     }
  267.                 });
  268.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  269.                 Log("循环添加 完成,耗时:" + time + "秒");
  270.             });
  271.         }
  272.         #endregion
  273.         #region 查询
  274.         private void button9_Click(object sender, EventArgs e)
  275.         {
  276.             RunTask(() =>
  277.             {
  278.                 _db.Queryable<SysUser>().Where(t => t.Id == 1).ToList(); //预热
  279.                 Log("查询 开始");
  280.                 DateTime dt = DateTime.Now;
  281.                 for (int i = 0; i < 10; i++)
  282.                 {
  283.                     List<SysUser> userList = _db.Queryable<SysUser>().Where(t => t.Id > 20 && t.RealName.Contains("测试")).OrderByDescending(t => t.CreateTime).OrderBy(t => t.Id).ToList();
  284.                     Log("查询结果 count=" + userList.Count.ToString());
  285.                 }
  286.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  287.                 Log("查询 完成,耗时:" + time + "秒");
  288.             });
  289.         }
  290.         #endregion
  291.         #region 分页查询
  292.         private void button8_Click(object sender, EventArgs e)
  293.         {
  294.             RunTask(() =>
  295.             {
  296.                 _db.Queryable<SysUser>().Where(t => t.Id == 1).ToList(); //预热
  297.                 Log("分页查询 开始");
  298.                 DateTime dt = DateTime.Now;
  299.                 for (int i = 0; i < 10; i++)
  300.                 {
  301.                     long total = _db.Queryable<SysUser>().Count();
  302.                     int pageSize = 100;
  303.                     int pageCount = (int)((total - 1) / pageSize + 1);
  304.                     List<SysUser> userList = new List<SysUser>();
  305.                     for (int page = 1; page <= pageCount; page++)
  306.                     {
  307.                         userList.AddRange(_db.Queryable<SysUser>().Where(t => t.Id > 20 && t.RealName.Contains("测试")).OrderByDescending(t => t.CreateTime).OrderBy(t => t.Id).Page(page, pageSize).ToList());
  308.                     }
  309.                     Log("分页查询结果 count=" + userList.Count.ToString());
  310.                 }
  311.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  312.                 Log("分页查询 完成,耗时:" + time + "秒");
  313.             });
  314.         }
  315.         #endregion
  316.         #region 并发查询
  317.         private void button11_Click(object sender, EventArgs e)
  318.         {
  319.             ThreadPool.SetMaxThreads(1000, 1000);
  320.             ThreadPool.SetMinThreads(200, 200);
  321.             RunTask(() =>
  322.             {
  323.                 Log("并发查询 开始");
  324.                 DateTime dt = DateTime.Now;
  325.                 List<Task> tasks = new List<Task>();
  326.                 for (int i = 1; i <= 1000; i++)
  327.                 {
  328.                     int index = i;
  329.                     Task task = RunTask(() =>
  330.                     {
  331.                         List<SysUser> userList = _db.Queryable<SysUser>()
  332.                             .Where(t => t.Id > 20 && t.RealName.Contains("测试"))
  333.                             .OrderByDescending(t => t.CreateTime).OrderBy(t => t.Id).ToList();
  334.                         if (index % 50 == 0) Log("第" + index + "次查询结果 count=" + userList.Count);
  335.                     });
  336.                     tasks.Add(task);
  337.                 }
  338.                 Task.WaitAll(tasks.ToArray());
  339.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  340.                 Log("并发查询 完成,耗时:" + time + "秒");
  341.             });
  342.         }
  343.         #endregion
  344.         #region 并发插入
  345.         private void button12_Click(object sender, EventArgs e)
  346.         {
  347.             ThreadPool.SetMaxThreads(1000, 1000);
  348.             ThreadPool.SetMinThreads(200, 200);
  349.             RunTask(() =>
  350.             {
  351.                 List<SysUser> userList = new List<SysUser>();
  352.                 for (int i = 1; i <= _count; i++)
  353.                 {
  354.                     SysUser user = new SysUser();
  355.                     user.UserName = "testUser";
  356.                     user.RealName = "测试插入用户";
  357.                     user.Remark = "测试插入用户" + i;
  358.                     user.Password = "123456";
  359.                     user.CreateUserid = "1";
  360.                     user.CreateTime = DateTime.Now;
  361.                     userList.Add(user);
  362.                 }
  363.                 Log("并发插入 开始 count=" + userList.Count);
  364.                 DateTime dt = DateTime.Now;
  365.                 List<Task> tasks = new List<Task>();
  366.                 foreach (SysUser item in userList)
  367.                 {
  368.                     var task = RunTask(user =>
  369.                     {
  370.                         _db.Insert(user).ExecuteIdentity();
  371.                     }, item);
  372.                     tasks.Add(task);
  373.                 }
  374.                 Task.WaitAll(tasks.ToArray());
  375.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  376.                 Log("并发插入 完成,耗时:" + time + "秒");
  377.             });
  378.         }
  379.         #endregion
  380.     }
  381. }
复制代码
SqlSugar net461

注意:需要把connection timeout设置大一点,才能通过测试。
  1. public class SqlSugarUtil
  2. {
  3.     public static readonly string ConnectionString = "Data Source=localhost;Port=3306;User ID=root;Password=123456;Initial Catalog=sqlsugar_test;Charset=utf8mb4;SslMode=none;Allow User Variables=True;connection timeout=600;";
  4.     #region CreateSqlSugarClient
  5.     public static SqlSugarScope CreateSqlSugarClient()
  6.     {
  7.         SqlSugarScope db = new SqlSugarScope(new ConnectionConfig()
  8.         {
  9.             ConnectionString = ConnectionString,//连接符字串
  10.             DbType = SqlSugar.DbType.MySql, //数据库类型
  11.             IsAutoCloseConnection = true //不设成true要手动close
  12.         });
  13.         return db;
  14.     }
  15.     #endregion
  16.     #region CreateModels 生成实体类
  17.     /// <summary>
  18.     /// 生成实体类
  19.     /// </summary>
  20.     public static void CreateModels(SqlSugarClient db, string tableName = null)
  21.     {
  22.         ......此处省略
  23.     }
  24.     #endregion
  25. }
复制代码
  1. using Models;
  2. using NLog;
  3. using SqlSugar;
  4. using SqlSugarDemo.Utils;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.ComponentModel;
  8. using System.Data;
  9. using System.Drawing;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Threading;
  13. using System.Threading.Tasks;
  14. using System.Windows.Forms;
  15. namespace SqlSugarDemo
  16. {
  17.     public partial class Form1 : Form
  18.     {
  19.         #region 变量
  20.         private Logger _log = NLog.LogManager.GetCurrentClassLogger();
  21.         private SqlSugarScope _db;
  22.         private int _count = 10000;
  23.         private bool _printSql = false;
  24.         #endregion
  25.         #region Form1
  26.         public Form1()
  27.         {
  28.             InitializeComponent();
  29.         }
  30.         #endregion
  31.         #region Form1_Load
  32.         private void Form1_Load(object sender, EventArgs e)
  33.         {
  34.             _db = SqlSugarUtil.CreateSqlSugarClient();
  35.             if (_printSql)
  36.             {
  37.                 _db.Aop.OnLogExecuting = OnLogExecuting;
  38.             }
  39.             RunTask(() =>
  40.             {
  41.                 _db.Queryable<SysUser>().Count(); //预热
  42.                 Log("预热完成");
  43.             });
  44.         }
  45.         #endregion
  46.         #region Log
  47.         private void Log(string log)
  48.         {
  49.             if (!this.IsDisposed)
  50.             {
  51.                 string msg = DateTime.Now.ToString("mm:ss.fff") + " " + log + "\r\n\r\n";
  52.                 if (this.InvokeRequired)
  53.                 {
  54.                     this.BeginInvoke(new Action(() =>
  55.                     {
  56.                         textBox1.AppendText(msg);
  57.                     }));
  58.                 }
  59.                 else
  60.                 {
  61.                     textBox1.AppendText(msg);
  62.                 }
  63.             }
  64.         }
  65.         #endregion
  66.         #region 清空输出框
  67.         private void button10_Click(object sender, EventArgs e)
  68.         {
  69.             textBox1.Text = string.Empty;
  70.         }
  71.         #endregion
  72.         #region RunTask
  73.         private Task RunTask(Action action)
  74.         {
  75.             return Task.Run(() =>
  76.             {
  77.                 try
  78.                 {
  79.                     action();
  80.                 }
  81.                 catch (Exception ex)
  82.                 {
  83.                     Log(ex.Message + "\r\n" + ex.StackTrace);
  84.                 }
  85.             });
  86.         }
  87.         private Task RunTask<T>(Action<T> action, T t)
  88.         {
  89.             return Task.Factory.StartNew(obj =>
  90.             {
  91.                 try
  92.                 {
  93.                     action((T)obj);
  94.                 }
  95.                 catch (Exception ex)
  96.                 {
  97.                     Log(ex.ToString());
  98.                 }
  99.             }, t);
  100.         }
  101.         #endregion
  102.         #region cbxPrintSql_Click
  103.         private void cbxPrintSql_CheckedChanged(object sender, EventArgs e)
  104.         {
  105.             _printSql = cbxPrintSql.Checked;
  106.         }
  107.         #endregion
  108.         #region 打印SQL
  109.         private void OnLogExecuting(string sql, SugarParameter[] paramArr)
  110.         {
  111.             if (_printSql)
  112.             {
  113.                 RunTask(() =>
  114.                 {
  115.                     //string msg = "SQL:" + sql + "\r\nParam:" + _db.Utilities.SerializeObject(paramArr.ToDictionary(it => it.ParameterName, it => it.Value));
  116.                     Console.WriteLine(sql);
  117.                     _log.Debug(sql);
  118.                 });
  119.             }
  120.         }
  121.         #endregion
  122.         #region 生成实体类
  123.         private void button1_Click(object sender, EventArgs e)
  124.         {
  125.             RunTask(() =>
  126.             {
  127.                 Log("开始生成实体类");
  128.                 SqlSugarUtil.CreateModels(new SqlSugarClient(new ConnectionConfig()
  129.                 {
  130.                     ConnectionString = SqlSugarUtil.ConnectionString,//连接符字串
  131.                     DbType = SqlSugar.DbType.MySql, //数据库类型
  132.                     IsAutoCloseConnection = true //不设成true要手动close
  133.                 }));
  134.                 Log("生成实体类完成");
  135.             });
  136.         }
  137.         #endregion
  138.         #region 测试查询
  139.         private void button2_Click(object sender, EventArgs e)
  140.         {
  141.             Log("开始查询");
  142.             SysUser conditionModel = new SysUser();
  143.             conditionModel.Remark = "管理员";
  144.             string remark = "管理员";
  145.             List<SysUser> list = _db.Queryable<SysUser>().Where(t => t.Id < 20 && t.Remark.Contains(conditionModel.Remark) && t.CreateTime > new DateTime(2010, 1, 1)).ToList();
  146.             foreach (SysUser user in list)
  147.             {
  148.                 Log(string.Format("{0},{1},{2},{3}", user.UserName, user.RealName, user.Remark, user.CreateTime.ToString("yyyy-MM-dd")));
  149.             }
  150.             Log("查询结束 count=" + list.Count);
  151.         }
  152.         #endregion
  153.         #region 测试批量修改
  154.         private void button3_Click(object sender, EventArgs e)
  155.         {
  156.             RunTask(() =>
  157.             {
  158.                 Random rnd = new Random();
  159.                 List<SysUser> userList = _db.Queryable<SysUser>().Where(t => t.Id > 20).ToList();
  160.                 Log("批量修改 开始 count=" + userList.Count.ToString("0 000"));
  161.                 foreach (SysUser user in userList)
  162.                 {
  163.                     user.Remark = "测试修改用户" + rnd.Next(0, 10000);
  164.                     user.UpdateUserid = "1";
  165.                     user.UpdateTime = DateTime.Now;
  166.                 }
  167.                 DateTime dt = DateTime.Now;
  168.                 try
  169.                 {
  170.                     _db.Ado.BeginTran();
  171.                     _db.Updateable(userList).ExecuteCommand();
  172.                     _db.Ado.CommitTran();
  173.                 }
  174.                 catch (Exception ex)
  175.                 {
  176.                     _db.Ado.RollbackTran();
  177.                     throw ex;
  178.                 }
  179.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  180.                 Log("批量修改 完成,耗时:" + time + "秒");
  181.             });
  182.         }
  183.         #endregion
  184.         #region 测试批量添加
  185.         private void button4_Click(object sender, EventArgs e)
  186.         {
  187.             RunTask(() =>
  188.             {
  189.                 List<SysUser> userList = new List<SysUser>();
  190.                 for (int i = 1; i <= _count; i++)
  191.                 {
  192.                     SysUser user = new SysUser();
  193.                     user.UserName = "testUser";
  194.                     user.RealName = "测试插入用户";
  195.                     user.Password = "123456";
  196.                     user.CreateUserid = "1";
  197.                     user.CreateTime = DateTime.Now;
  198.                     userList.Add(user);
  199.                 }
  200.                 Log("批量添加 开始 count=" + userList.Count);
  201.                 DateTime dt = DateTime.Now;
  202.                 try
  203.                 {
  204.                     _db.Ado.BeginTran();
  205.                     _db.Insertable(userList).ExecuteCommand();
  206.                     _db.Ado.CommitTran();
  207.                 }
  208.                 catch (Exception ex)
  209.                 {
  210.                     _db.Ado.RollbackTran();
  211.                     throw ex;
  212.                 }
  213.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  214.                 Log("批量添加 结束,完成:" + time + "秒");
  215.             });
  216.         }
  217.         #endregion
  218.         #region 删除
  219.         private void button5_Click(object sender, EventArgs e)
  220.         {
  221.             RunTask(() =>
  222.             {
  223.                 Log("删除 开始");
  224.                 _db.Deleteable<SysUser>(t => t.Id > 20).ExecuteCommand();
  225.                 Log("删除 完成");
  226.             });
  227.         }
  228.         #endregion
  229.         #region 测试循环修改
  230.         private void button7_Click(object sender, EventArgs e)
  231.         {
  232.             RunTask(() =>
  233.             {
  234.                 Random rnd = new Random();
  235.                 List<SysUser> userList = _db.Queryable<SysUser>().Where(t => t.Id > 20).ToList();
  236.                 Log("循环修改 开始 count=" + userList.Count.ToString("0 000"));
  237.                 foreach (SysUser user in userList)
  238.                 {
  239.                     user.Remark = "测试修改用户" + rnd.Next(0, 10000);
  240.                     user.UpdateUserid = "1";
  241.                     user.UpdateTime = DateTime.Now;
  242.                 }
  243.                 DateTime dt = DateTime.Now;
  244.                 try
  245.                 {
  246.                     _db.Ado.BeginTran();
  247.                     foreach (SysUser user in userList)
  248.                     {
  249.                         _db.Updateable(user).ExecuteCommand();
  250.                     }
  251.                     _db.Ado.CommitTran();
  252.                 }
  253.                 catch (Exception ex)
  254.                 {
  255.                     _db.Ado.RollbackTran();
  256.                     throw ex;
  257.                 }
  258.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  259.                 Log("循环修改 完成,耗时:" + time + "秒");
  260.             });
  261.         }
  262.         #endregion
  263.         #region 测试循环添加
  264.         private void button6_Click(object sender, EventArgs e)
  265.         {
  266.             RunTask(() =>
  267.             {
  268.                 List<SysUser> userList = new List<SysUser>();
  269.                 for (int i = 1; i <= _count; i++)
  270.                 {
  271.                     SysUser user = new SysUser();
  272.                     user.UserName = "testUser";
  273.                     user.RealName = "测试插入用户";
  274.                     user.Password = "123456";
  275.                     user.CreateUserid = "1";
  276.                     user.CreateTime = DateTime.Now;
  277.                     userList.Add(user);
  278.                 }
  279.                 Log("循环添加 开始 count=" + userList.Count);
  280.                 DateTime dt = DateTime.Now;
  281.                 try
  282.                 {
  283.                     _db.Ado.BeginTran();
  284.                     foreach (SysUser user in userList)
  285.                     {
  286.                         _db.Insertable(user).ExecuteCommand();
  287.                     }
  288.                     _db.Ado.CommitTran();
  289.                 }
  290.                 catch (Exception ex)
  291.                 {
  292.                     _db.Ado.RollbackTran();
  293.                     throw ex;
  294.                 }
  295.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  296.                 Log("循环添加 完成,耗时:" + time + "秒");
  297.             });
  298.         }
  299.         #endregion
  300.         #region 查询
  301.         private void button9_Click(object sender, EventArgs e)
  302.         {
  303.             RunTask(() =>
  304.             {
  305.                 _db.Queryable<SysUser>().Where(t => t.Id == 1).ToList(); //预热
  306.                 Log("查询 开始");
  307.                 DateTime dt = DateTime.Now;
  308.                 for (int i = 0; i < 10; i++)
  309.                 {
  310.                     List<SysUser> userList = _db.Queryable<SysUser>().Where(t => t.Id > 20 && t.RealName.Contains("测试")).OrderBy(t => t.CreateTime, OrderByType.Desc).OrderBy(t => t.Id).ToList();
  311.                     Log("查询结果 count=" + userList.Count.ToString());
  312.                 }
  313.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  314.                 Log("查询 完成,耗时:" + time + "秒");
  315.             });
  316.         }
  317.         #endregion
  318.         #region 分页查询
  319.         private void button8_Click(object sender, EventArgs e)
  320.         {
  321.             RunTask(() =>
  322.             {
  323.                 _db.Queryable<SysUser>().Where(t => t.Id == 1).ToList(); //预热
  324.                 Log("分页查询 开始");
  325.                 DateTime dt = DateTime.Now;
  326.                 for (int i = 0; i < 10; i++)
  327.                 {
  328.                     int total = _db.Queryable<SysUser>().Count();
  329.                     int pageSize = 100;
  330.                     int pageCount = (total - 1) / pageSize + 1;
  331.                     List<SysUser> userList = new List<SysUser>();
  332.                     for (int page = 1; page <= pageCount; page++)
  333.                     {
  334.                         userList.AddRange(_db.Queryable<SysUser>().Where(t => t.Id > 20 && t.RealName.Contains("测试")).OrderBy(t => t.CreateTime, OrderByType.Desc).OrderBy(t => t.Id).ToPageList(page, pageSize));
  335.                     }
  336.                     Log("分页查询结果 count=" + userList.Count.ToString());
  337.                 }
  338.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  339.                 Log("分页查询 完成,耗时:" + time + "秒");
  340.             });
  341.         }
  342.         #endregion
  343.         #region 并发查询
  344.         private void button11_Click(object sender, EventArgs e)
  345.         {
  346.             ThreadPool.SetMaxThreads(1000, 1000);
  347.             ThreadPool.SetMinThreads(200, 200);
  348.             RunTask(() =>
  349.             {
  350.                 Log("并发查询 开始");
  351.                 DateTime dt = DateTime.Now;
  352.                 List<Task> tasks = new List<Task>();
  353.                 for (int i = 1; i <= 1000; i++)
  354.                 {
  355.                     int index = i;
  356.                     Task task = RunTask(() =>
  357.                     {
  358.                         List<SysUser> userList = _db.Queryable<SysUser>().Where(t => t.Id > 20 && t.RealName.Contains("测试")).OrderBy(t => t.CreateTime, OrderByType.Desc).OrderBy(t => t.Id).ToList();
  359.                         if (index % 50 == 0) Log("第" + index + "次查询结果 count=" + userList.Count);
  360.                     });
  361.                     tasks.Add(task);
  362.                 }
  363.                 Task.WaitAll(tasks.ToArray());
  364.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  365.                 Log("并发查询 完成,耗时:" + time + "秒");
  366.             });
  367.         }
  368.         #endregion
  369.         #region 并发插入
  370.         private void button12_Click(object sender, EventArgs e)
  371.         {
  372.             ThreadPool.SetMaxThreads(1000, 1000);
  373.             ThreadPool.SetMinThreads(200, 200);
  374.             RunTask(() =>
  375.             {
  376.                 List<SysUser> userList = new List<SysUser>();
  377.                 for (int i = 1; i <= _count; i++)
  378.                 {
  379.                     SysUser user = new SysUser();
  380.                     user.UserName = "testUser";
  381.                     user.RealName = "测试插入用户";
  382.                     user.Remark = "测试插入用户" + i;
  383.                     user.Password = "123456";
  384.                     user.CreateUserid = "1";
  385.                     user.CreateTime = DateTime.Now;
  386.                     userList.Add(user);
  387.                 }
  388.                 Log("并发插入 开始 count=" + userList.Count);
  389.                 DateTime dt = DateTime.Now;
  390.                 List<Task> tasks = new List<Task>();
  391.                 foreach (SysUser item in userList)
  392.                 {
  393.                     var task = RunTask(user =>
  394.                     {
  395.                         _db.Insertable(user).ExecuteCommand();
  396.                     }, item);
  397.                     tasks.Add(task);
  398.                 }
  399.                 Task.WaitAll(tasks.ToArray());
  400.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  401.                 Log("并发插入 完成,耗时:" + time + "秒");
  402.             });
  403.         }
  404.         #endregion
  405.     }
  406. }
复制代码
Entity Framework

数据库连接字符串:
注意:connection timeout要设置大一点,不然会报错。
  1. Data Source=localhost;Port=3306;User ID=root;Password=123456;Initial Catalog=entityframework_test;Charset=utf8mb4;SslMode=none;Allow User Variables=True;connection timeout=600;
复制代码
DatabaseContext 类:
DbContext不能跨线程使用。
  1. [DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
  2. public class DatabaseContext : DbContext
  3. {
  4.     public DatabaseContext() : base("name=DefaultConnection")
  5.     {
  6.     }
  7.     protected override void OnModelCreating(DbModelBuilder modelBuilder)
  8.     {
  9.         base.OnModelCreating(modelBuilder);
  10.         modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
  11.     }
  12.     public DbSet<SysUser> SysUser { get; set; }
  13. }
复制代码
测试代码:
  1. using Models;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Drawing;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. using System.Windows.Forms;
  12. namespace EFDemo
  13. {
  14.     public partial class Form1 : Form
  15.     {
  16.         #region 变量
  17.         private DatabaseContext _db = new DatabaseContext();
  18.         private int _count = 10000;
  19.         private bool _printSql = false;
  20.         #endregion
  21.         #region Form1
  22.         public Form1()
  23.         {
  24.             InitializeComponent();
  25.         }
  26.         #endregion
  27.         #region Form1_Load
  28.         private void Form1_Load(object sender, EventArgs e)
  29.         {
  30.             _db = new DatabaseContext();
  31.             if (_printSql)
  32.             {
  33.                 _db.Database.Log = OnLogExecuting;
  34.             }
  35.             RunTask(() =>
  36.             {
  37.                 _db.Set<SysUser>().First();  //预热
  38.                 Log("预热完成");
  39.             });
  40.         }
  41.         #endregion
  42.         private void cbxPrintSql_Click(object sender, EventArgs e)
  43.         {
  44.             _printSql = cbxPrintSql.Checked;
  45.         }
  46.         #region Log
  47.         private void Log(string log)
  48.         {
  49.             if (!this.IsDisposed)
  50.             {
  51.                 string msg = DateTime.Now.ToString("mm:ss.fff") + " " + log + "\r\n\r\n";
  52.                 if (this.InvokeRequired)
  53.                 {
  54.                     this.BeginInvoke(new Action(() =>
  55.                     {
  56.                         textBox1.AppendText(msg);
  57.                     }));
  58.                 }
  59.                 else
  60.                 {
  61.                     textBox1.AppendText(msg);
  62.                 }
  63.             }
  64.         }
  65.         #endregion
  66.         #region 清空输出框
  67.         private void button10_Click(object sender, EventArgs e)
  68.         {
  69.             textBox1.Text = string.Empty;
  70.         }
  71.         #endregion
  72.         #region RunTask
  73.         private Task RunTask(Action action)
  74.         {
  75.             return Task.Run(() =>
  76.             {
  77.                 try
  78.                 {
  79.                     action();
  80.                 }
  81.                 catch (Exception ex)
  82.                 {
  83.                     Log(ex.ToString());
  84.                 }
  85.             });
  86.         }
  87.         private Task RunTask<T>(Action<T> action, T t)
  88.         {
  89.             return Task.Factory.StartNew(obj =>
  90.             {
  91.                 try
  92.                 {
  93.                     action((T)obj);
  94.                 }
  95.                 catch (Exception ex)
  96.                 {
  97.                     Log(ex.ToString());
  98.                     throw;
  99.                 }
  100.             }, t);
  101.         }
  102.         #endregion
  103.         #region 打印SQL
  104.         private void OnLogExecuting(string sql)
  105.         {
  106.             if (_printSql)
  107.             {
  108.                 RunTask(() =>
  109.                 {
  110.                     string msg = "SQL:" + sql;
  111.                     Console.WriteLine(msg);
  112.                 });
  113.             }
  114.         }
  115.         #endregion
  116.         #region 生成实体类
  117.         private void button1_Click(object sender, EventArgs e)
  118.         {
  119.             RunTask(() =>
  120.             {
  121.                 Log("开始生成实体类");
  122.                 Log("生成实体类完成");
  123.             });
  124.         }
  125.         #endregion
  126.         #region 测试查询
  127.         private void button2_Click(object sender, EventArgs e)
  128.         {
  129.             Log("开始查询");
  130.             SysUser conditionModel = new SysUser();
  131.             conditionModel.Remark = "管理员";
  132.             string remark = "管理员";
  133.             List<SysUser> list = _db.Set<SysUser>().Where(t => t.Id < 20 && t.Remark.Contains(conditionModel.Remark) && t.CreateTime > new DateTime(2010, 1, 1)).ToList();
  134.             foreach (SysUser user in list)
  135.             {
  136.                 Log(string.Format("{0},{1},{2},{3}", user.UserName, user.RealName, user.Remark, user.CreateTime.ToString("yyyy-MM-dd")));
  137.             }
  138.             Log("查询结束 count=" + list.Count);
  139.         }
  140.         #endregion
  141.         #region 测试批量修改
  142.         private void button3_Click(object sender, EventArgs e)
  143.         {
  144.             RunTask(() =>
  145.             {
  146.                 Random rnd = new Random();
  147.                 List<SysUser> userList = _db.Set<SysUser>().Where(t => t.Id > 20).ToList();
  148.                 Log("批量修改 开始 count=" + userList.Count.ToString("0 000"));
  149.                 foreach (SysUser user in userList)
  150.                 {
  151.                     user.Remark = "测试修改用户" + rnd.Next(0, 10000);
  152.                     user.UpdateUserid = "1";
  153.                     user.UpdateTime = DateTime.Now;
  154.                 }
  155.                 DateTime dt = DateTime.Now;
  156.                 _db.SaveChanges();
  157.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  158.                 Log("批量修改 完成,耗时:" + time + "秒");
  159.             });
  160.         }
  161.         #endregion
  162.         #region 测试批量添加
  163.         private void button4_Click(object sender, EventArgs e)
  164.         {
  165.             RunTask(() =>
  166.             {
  167.                 List<SysUser> userList = new List<SysUser>();
  168.                 for (int i = 1; i <= _count; i++)
  169.                 {
  170.                     SysUser user = new SysUser();
  171.                     user.UserName = "testUser";
  172.                     user.RealName = "测试插入用户";
  173.                     user.Password = "123456";
  174.                     user.CreateUserid = "1";
  175.                     user.CreateTime = DateTime.Now;
  176.                     userList.Add(user);
  177.                 }
  178.                 Log("批量添加 开始 count=" + userList.Count);
  179.                 DateTime dt = DateTime.Now;
  180.                 _db.Set<SysUser>().AddRange(userList);
  181.                 _db.SaveChanges();
  182.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  183.                 Log("批量添加 结束,完成:" + time + "秒");
  184.             });
  185.         }
  186.         #endregion
  187.         #region 删除
  188.         private void button5_Click(object sender, EventArgs e)
  189.         {
  190.             RunTask(() =>
  191.             {
  192.                 Log("删除 开始");
  193.                 _db.Set<SysUser>().RemoveRange(_db.Set<SysUser>().Where(t => t.Id > 20));
  194.                 _db.SaveChanges();
  195.                 Log("删除 完成");
  196.             });
  197.         }
  198.         #endregion
  199.         #region 测试循环修改
  200.         private void button7_Click(object sender, EventArgs e)
  201.         {
  202.             RunTask(() =>
  203.             {
  204.                 Random rnd = new Random();
  205.                 List<SysUser> userList = _db.Set<SysUser>().Where(t => t.Id > 20).ToList();
  206.                 Log("循环修改 开始 count=" + userList.Count.ToString("0 000"));
  207.                 foreach (SysUser user in userList)
  208.                 {
  209.                     user.Remark = "测试修改用户" + rnd.Next(0, 10000);
  210.                     user.UpdateUserid = "1";
  211.                     user.UpdateTime = DateTime.Now;
  212.                 }
  213.                 DateTime dt = DateTime.Now;
  214.                 _db.SaveChanges();
  215.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  216.                 Log("循环修改 完成,耗时:" + time + "秒");
  217.             });
  218.         }
  219.         #endregion
  220.         #region 测试循环添加
  221.         private void button6_Click(object sender, EventArgs e)
  222.         {
  223.             RunTask(() =>
  224.             {
  225.                 List<SysUser> userList = new List<SysUser>();
  226.                 for (int i = 1; i <= _count; i++)
  227.                 {
  228.                     SysUser user = new SysUser();
  229.                     user.UserName = "testUser";
  230.                     user.RealName = "测试插入用户";
  231.                     user.Password = "123456";
  232.                     user.CreateUserid = "1";
  233.                     user.CreateTime = DateTime.Now;
  234.                     userList.Add(user);
  235.                 }
  236.                 Log("循环添加 开始 count=" + userList.Count);
  237.                 DateTime dt = DateTime.Now;
  238.                 _db.Set<SysUser>().AddRange(userList);
  239.                 _db.SaveChanges();
  240.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  241.                 Log("循环添加 完成,耗时:" + time + "秒");
  242.             });
  243.         }
  244.         #endregion
  245.         #region 查询
  246.         private void button9_Click(object sender, EventArgs e)
  247.         {
  248.             RunTask(() =>
  249.             {
  250.                 _db.Set<SysUser>().Where(t => t.Id == 1).ToList(); //预热
  251.                 Log("查询 开始");
  252.                 DateTime dt = DateTime.Now;
  253.                 for (int i = 0; i < 10; i++)
  254.                 {
  255.                     List<SysUser> userList = _db.Set<SysUser>().Where(t => t.Id > 20 && t.RealName.Contains("测试")).OrderByDescending(t => t.CreateTime).ThenBy(t => t.Id).ToList();
  256.                     Log("查询结果 count=" + userList.Count.ToString());
  257.                 }
  258.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  259.                 Log("查询 完成,耗时:" + time + "秒");
  260.             });
  261.         }
  262.         #endregion
  263.         #region 分页查询
  264.         private void button8_Click(object sender, EventArgs e)
  265.         {
  266.             RunTask(() =>
  267.             {
  268.                 _db.Set<SysUser>().Where(t => t.Id == 1).ToList(); //预热
  269.                 Log("分页查询 开始");
  270.                 DateTime dt = DateTime.Now;
  271.                 for (int i = 0; i < 10; i++)
  272.                 {
  273.                     int total = _db.Set<SysUser>().Count();
  274.                     int pageSize = 100;
  275.                     int pageCount = (total - 1) / pageSize + 1;
  276.                     List<SysUser> userList = new List<SysUser>();
  277.                     for (int page = 1; page <= pageCount; page++)
  278.                     {
  279.                         userList.AddRange(_db.Set<SysUser>().Where(t => t.Id > 20 && t.RealName.Contains("测试")).OrderByDescending(t => t.CreateTime).ThenBy(t => t.Id).Skip(pageSize * (page - 1)).Take(pageSize));
  280.                     }
  281.                     Log("分页查询结果 count=" + userList.Count.ToString());
  282.                 }
  283.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  284.                 Log("分页查询 完成,耗时:" + time + "秒");
  285.             });
  286.         }
  287.         #endregion
  288.         #region 并发查询
  289.         private void button11_Click(object sender, EventArgs e)
  290.         {
  291.             ThreadPool.SetMaxThreads(1000, 1000);
  292.             ThreadPool.SetMinThreads(200, 200);
  293.             RunTask(() =>
  294.             {
  295.                 Log("并发查询 开始");
  296.                 DateTime dt = DateTime.Now;
  297.                 List<Task> tasks = new List<Task>();
  298.                 for (int i = 1; i <= 1000; i++)
  299.                 {
  300.                     int index = i;
  301.                     Task task = RunTask(() =>
  302.                     {
  303.                         DatabaseContext db = new DatabaseContext();
  304.                         List<SysUser> userList = db.Set<SysUser>()
  305.                             .Where(t => t.Id > 20 && t.RealName.Contains("测试"))
  306.                             .OrderByDescending(t => t.CreateTime)
  307.                             .ThenBy(t => t.Id).ToList();
  308.                         if (index % 50 == 0) Log("第" + index + "次查询结果 count=" + userList.Count);
  309.                     });
  310.                     tasks.Add(task);
  311.                 }
  312.                 Task.WaitAll(tasks.ToArray());
  313.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  314.                 Log("并发查询 完成,耗时:" + time + "秒");
  315.             });
  316.         }
  317.         #endregion
  318.         #region 并发插入
  319.         private void button12_Click(object sender, EventArgs e)
  320.         {
  321.             ThreadPool.SetMaxThreads(1000, 1000);
  322.             ThreadPool.SetMinThreads(200, 200);
  323.             RunTask(() =>
  324.             {
  325.                 List<SysUser> userList = new List<SysUser>();
  326.                 for (int i = 1; i <= _count; i++)
  327.                 {
  328.                     SysUser user = new SysUser();
  329.                     user.UserName = "testUser";
  330.                     user.RealName = "测试插入用户";
  331.                     user.Remark = "测试插入用户" + i;
  332.                     user.Password = "123456";
  333.                     user.CreateUserid = "1";
  334.                     user.CreateTime = DateTime.Now;
  335.                     userList.Add(user);
  336.                 }
  337.                 Log("并发插入 开始 count=" + userList.Count);
  338.                 DateTime dt = DateTime.Now;
  339.                 List<Task> tasks = new List<Task>();
  340.                 foreach (SysUser item in userList)
  341.                 {
  342.                     var task = RunTask(user =>
  343.                     {
  344.                         DatabaseContext db = new DatabaseContext();
  345.                         db.Set<SysUser>().Add(user);
  346.                         db.SaveChanges();
  347.                     }, item);
  348.                     tasks.Add(task);
  349.                 }
  350.                 Task.WaitAll(tasks.ToArray());
  351.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  352.                 Log("并发插入 完成,耗时:" + time + "秒");
  353.             });
  354.         }
  355.         #endregion
  356.     }
  357. }
复制代码
Fast.Framework net6
  1. using Fast.Framework;
  2. using Fast.Framework.Interfaces;
  3. using Fast.Framework.Models;
  4. using Fast.Framework.Extensions;
  5. using Fast.Framework.Aop;
  6. using Models;
  7. namespace FastFrameworkDemo
  8. {
  9.     public partial class Form1 : Form
  10.     {
  11.         #region 变量
  12.         private Random _rnd = new Random();
  13.         private int _count = 10000;
  14.         private bool _printSql = false;
  15.         #endregion
  16.         #region Form1
  17.         public Form1()
  18.         {
  19.             InitializeComponent();
  20.         }
  21.         #endregion
  22.         #region Form1_Load
  23.         private void Form1_Load(object sender, EventArgs e)
  24.         {
  25.             RunTask(async () =>
  26.             {
  27.                 await GetDbContext().Query<SysUser>().CountAsync();
  28.                 Log("预热完成");
  29.             });
  30.         }
  31.         #endregion
  32.         #region Log
  33.         private void Log(string log)
  34.         {
  35.             if (!this.IsDisposed)
  36.             {
  37.                 string msg = DateTime.Now.ToString("mm:ss.fff") + " " + log + "\r\n\r\n";
  38.                 if (this.InvokeRequired)
  39.                 {
  40.                     this.BeginInvoke(new Action(() =>
  41.                     {
  42.                         textBox1.AppendText(msg);
  43.                     }));
  44.                 }
  45.                 else
  46.                 {
  47.                     textBox1.AppendText(msg);
  48.                 }
  49.             }
  50.         }
  51.         #endregion
  52.         #region 清空输出框
  53.         private void button10_Click(object sender, EventArgs e)
  54.         {
  55.             textBox1.Text = string.Empty;
  56.         }
  57.         #endregion
  58.         #region RunTask
  59.         private Task RunTask(Action action)
  60.         {
  61.             return Task.Run(() =>
  62.             {
  63.                 try
  64.                 {
  65.                     action();
  66.                 }
  67.                 catch (Exception ex)
  68.                 {
  69.                     Log(ex.ToString());
  70.                 }
  71.             });
  72.         }
  73.         private Task RunTask<T>(Action<T> action, T t)
  74.         {
  75.             return Task.Factory.StartNew(obj =>
  76.             {
  77.                 try
  78.                 {
  79.                     action((T)obj);
  80.                 }
  81.                 catch (Exception ex)
  82.                 {
  83.                     Log(ex.ToString());
  84.                 }
  85.             }, t);
  86.         }
  87.         #endregion
  88.         #region cbxPrintSql_Click
  89.         private void cbxPrintSql_Click(object sender, EventArgs e)
  90.         {
  91.             _printSql = cbxPrintSql.Checked;
  92.         }
  93.         #endregion
  94.         #region GetDbContext
  95.         private IDbContext GetDbContext()
  96.         {
  97.             IDbContext _db = new DbContext(new List<DbOptions>() {
  98.                     new DbOptions()
  99.                     {
  100.                       DbId = "1",
  101.                       DbType = DbType.MySQL,
  102.                       ProviderName = "MySqlConnector",
  103.                       FactoryName = "MySqlConnector.MySqlConnectorFactory,MySqlConnector",
  104.                       ConnectionStrings = "Data Source=localhost;Port=3306;User ID=root;Password=123456;Initial Catalog=fast_framework_test;Charset=utf8mb4;SslMode=none;Allow User Variables=True;"
  105.                     }
  106.                 });
  107.             if (_printSql)
  108.             {
  109.                 _db.Aop.DbLog = (sql, dp) =>
  110.                 {
  111.                     Console.WriteLine($"执行Sql:{sql}");
  112.                     if (dp != null)
  113.                     {
  114.                         foreach (var item in dp)
  115.                         {
  116.                             Console.WriteLine($"参数名称:{item.ParameterName} 参数值:{item.Value}");
  117.                         }
  118.                     }
  119.                 };
  120.             }
  121.             return _db;
  122.         }
  123.         #endregion
  124.         #region 删除
  125.         private void button1_Click(object sender, EventArgs e)
  126.         {
  127.             RunTask(async () =>
  128.             {
  129.                 Log("删除 开始");
  130.                 await GetDbContext().Delete<SysUser>().Where(t => t.Id > 20).ExceuteAsync();
  131.                 Log("删除 完成");
  132.             });
  133.         }
  134.         #endregion
  135.         #region 批量修改
  136.         private void button2_Click(object sender, EventArgs e)
  137.         {
  138.             RunTask(async () =>
  139.             {
  140.                 List<SysUser> userList = await GetDbContext().Query<SysUser>().Where(t => t.Id > 20).ToListAsync();
  141.                 Log("批量修改 开始 count=" + userList.Count);
  142.                 DateTime dt = DateTime.Now;
  143.                 try
  144.                 {
  145.                     foreach (SysUser user in userList)
  146.                     {
  147.                         user.Remark = "测试修改用户" + _rnd.Next(1, 10000);
  148.                         user.UpdateUserid = "1";
  149.                         user.UpdateTime = DateTime.Now;
  150.                     }
  151.                     await GetDbContext().Update(userList).ExceuteAsync();
  152.                 }
  153.                 catch
  154.                 {
  155.                     //todo:没有rollback?
  156.                     throw;
  157.                 }
  158.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  159.                 Log("批量修改 完成,耗时:" + time + "秒");
  160.             });
  161.         }
  162.         #endregion
  163.         #region 批量添加
  164.         private void button3_Click(object sender, EventArgs e)
  165.         {
  166.             RunTask(async () =>
  167.             {
  168.                 List<SysUser> userList = new List<SysUser>();
  169.                 for (int i = 1; i <= _count; i++)
  170.                 {
  171.                     SysUser user = new SysUser();
  172.                     user.UserName = "testUser";
  173.                     user.RealName = "测试插入用户";
  174.                     user.Password = "123456";
  175.                     user.CreateUserid = "1";
  176.                     user.CreateTime = DateTime.Now;
  177.                     userList.Add(user);
  178.                 }
  179.                 Log("批量添加 开始 count=" + userList.Count);
  180.                 DateTime dt = DateTime.Now;
  181.                 try
  182.                 {
  183.                     await GetDbContext().Insert(userList).ExceuteAsync();
  184.                 }
  185.                 catch
  186.                 {
  187.                     //todo:没有rollback?
  188.                     throw;
  189.                 }
  190.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  191.                 Log("批量添加 完成,耗时:" + time + "秒");
  192.             });
  193.         }
  194.         #endregion
  195.         #region 循环修改
  196.         private void button4_Click(object sender, EventArgs e)
  197.         {
  198.             RunTask(async () =>
  199.             {
  200.                 List<SysUser> userList = await GetDbContext().Query<SysUser>().Where(t => t.Id > 20).ToListAsync();
  201.                 Log("循环修改 开始 count=" + userList.Count);
  202.                 DateTime dt = DateTime.Now;
  203.                 try
  204.                 {
  205.                     foreach (SysUser user in userList)
  206.                     {
  207.                         user.Remark = "测试修改用户" + _rnd.Next(1, 10000);
  208.                         user.UpdateUserid = "1";
  209.                         user.UpdateTime = DateTime.Now;
  210.                     }
  211.                     var db = GetDbContext();
  212.                     await db.Ado.BeginTranAsync();
  213.                     foreach (SysUser user in userList)
  214.                     {
  215.                         await db.Update(user).ExceuteAsync();
  216.                     }
  217.                     await db.Ado.CommitTranAsync();
  218.                 }
  219.                 catch
  220.                 {
  221.                     //todo:没有rollback?
  222.                     throw;
  223.                 }
  224.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  225.                 Log("循环修改 完成,耗时:" + time + "秒");
  226.             });
  227.         }
  228.         #endregion
  229.         #region 循环添加
  230.         private void button5_Click(object sender, EventArgs e)
  231.         {
  232.             RunTask(async () =>
  233.             {
  234.                 List<SysUser> userList = new List<SysUser>();
  235.                 for (int i = 1; i <= _count; i++)
  236.                 {
  237.                     SysUser user = new SysUser();
  238.                     user.UserName = "testUser";
  239.                     user.RealName = "测试插入用户";
  240.                     user.Password = "123456";
  241.                     user.CreateUserid = "1";
  242.                     user.CreateTime = DateTime.Now;
  243.                     userList.Add(user);
  244.                 }
  245.                 Log("循环添加 开始 count=" + userList.Count);
  246.                 DateTime dt = DateTime.Now;
  247.                 try
  248.                 {
  249.                     var db = GetDbContext();
  250.                     await db.Ado.BeginTranAsync();
  251.                     foreach (SysUser user in userList)
  252.                     {
  253.                         await db.Insert(user).ExceuteAsync();
  254.                     }
  255.                     await db.Ado.CommitTranAsync();
  256.                 }
  257.                 catch
  258.                 {
  259.                     //todo:没有rollback?
  260.                     throw;
  261.                 }
  262.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  263.                 Log("循环添加 完成,耗时:" + time + "秒");
  264.             });
  265.         }
  266.         #endregion
  267.         #region 查询
  268.         private void button6_Click(object sender, EventArgs e)
  269.         {
  270.             RunTask(async () =>
  271.             {
  272.                 Log("查询 开始");
  273.                 DateTime dt = DateTime.Now;
  274.                 var db = GetDbContext();
  275.                 for (int i = 0; i < 10; i++)
  276.                 {
  277.                     List<SysUser> userList = await db.Query<SysUser>()
  278.                         .Where(t => t.Id > 20 && t.RealName.Contains("%测试%"))
  279.                         .OrderBy("create_time", "desc")
  280.                         .OrderBy("id", "asc").ToListAsync();
  281.                     Log("查询结果 count=" + userList.Count.ToString());
  282.                 }
  283.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  284.                 Log("查询 完成,耗时:" + time + "秒");
  285.             });
  286.         }
  287.         #endregion
  288.         #region 分页查询
  289.         private void button7_Click(object sender, EventArgs e)
  290.         {
  291.             Log("尚未实现");
  292.         }
  293.         #endregion
  294.         #region 并发查询
  295.         private void button8_Click(object sender, EventArgs e)
  296.         {
  297.             RunTask(() =>
  298.             {
  299.                 ThreadPool.SetMaxThreads(1000, 1000);
  300.                 ThreadPool.SetMinThreads(200, 200);
  301.                 Log("并发查询 开始");
  302.                 DateTime dt = DateTime.Now;
  303.                 List<Task> tasks = new List<Task>();
  304.                 for (int i = 1; i <= 1000; i++)
  305.                 {
  306.                     int index = i;
  307.                     Task task = RunTask(async () =>
  308.                     {
  309.                         List<SysUser> userList = await GetDbContext().Query<SysUser>()
  310.                             .Where(t => t.Id > 20 && t.RealName.Contains("%测试%"))
  311.                             .OrderBy("create_time", "desc")
  312.                             .OrderBy("id", "asc").ToListAsync();
  313.                         if (index % 50 == 0) Log("第" + index + "次查询结果 count=" + userList.Count);
  314.                     });
  315.                     tasks.Add(task);
  316.                 }
  317.                 Task.WaitAll(tasks.ToArray());
  318.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  319.                 Log("并发查询 完成,耗时:" + time + "秒");
  320.             });
  321.         }
  322.         #endregion
  323.         #region 并发插入
  324.         private void button9_Click(object sender, EventArgs e)
  325.         {
  326.             RunTask(() =>
  327.             {
  328.                 ThreadPool.SetMaxThreads(1000, 1000);
  329.                 ThreadPool.SetMinThreads(200, 200);
  330.                 List<SysUser> userList = new List<SysUser>();
  331.                 for (int i = 1; i <= _count; i++)
  332.                 {
  333.                     SysUser user = new SysUser();
  334.                     user.UserName = "testUser";
  335.                     user.RealName = "测试插入用户";
  336.                     user.Remark = "测试插入用户" + i;
  337.                     user.Password = "123456";
  338.                     user.CreateUserid = "1";
  339.                     user.CreateTime = DateTime.Now;
  340.                     userList.Add(user);
  341.                 }
  342.                 Log("并发插入 开始 count=" + userList.Count);
  343.                 DateTime dt = DateTime.Now;
  344.                 List<Task> tasks = new List<Task>();
  345.                 foreach (SysUser item in userList)
  346.                 {
  347.                     var task = RunTask(async user =>
  348.                     {
  349.                         await GetDbContext().Insert(user).ExceuteAsync();
  350.                     }, item);
  351.                     tasks.Add(task);
  352.                 }
  353.                 Task.WaitAll(tasks.ToArray());
  354.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  355.                 Log("并发插入 完成,耗时:" + time + "秒");
  356.             });
  357.         }
  358.         #endregion
  359.     }
  360. }
复制代码
Dapper.LiteSql net6
  1. using Dapper.LiteSql;
  2. using Models;
  3. using Provider;
  4. namespace DapperLiteSqlDemo
  5. {
  6.     public partial class Form1 : Form
  7.     {
  8.         #region 变量
  9.         private Random _rnd = new Random();
  10.         private int _count = 10000;
  11.         private bool _showSqlLog = false;
  12.         private ILiteSqlClient _db;
  13.         private bool _printSql = false;
  14.         #endregion
  15.         #region Form1
  16.         public Form1()
  17.         {
  18.             InitializeComponent();
  19.         }
  20.         #endregion
  21.         #region Form1_Load
  22.         private void Form1_Load(object sender, EventArgs e)
  23.         {
  24.             _db = new LiteSqlClient("Data Source=localhost;Port=3306;User ID=root;Password=123456;Initial Catalog=litesql_test;Charset=utf8mb4;SslMode=none;Allow User Variables=True;",
  25.                 DBType.MySQL, new MySQLProvider());
  26.             RunTask(() =>
  27.             {
  28.                 _db.GetSession(); //预热
  29.                 Log("预热完成");
  30.             });
  31.         }
  32.         #endregion
  33.         #region Log
  34.         private void Log(string log)
  35.         {
  36.             if (!this.IsDisposed)
  37.             {
  38.                 string msg = DateTime.Now.ToString("mm:ss.fff") + " " + log + "\r\n\r\n";
  39.                 if (this.InvokeRequired)
  40.                 {
  41.                     this.BeginInvoke(new Action(() =>
  42.                     {
  43.                         textBox1.AppendText(msg);
  44.                     }));
  45.                 }
  46.                 else
  47.                 {
  48.                     textBox1.AppendText(msg);
  49.                 }
  50.             }
  51.         }
  52.         #endregion
  53.         #region 清空输出框
  54.         private void button10_Click(object sender, EventArgs e)
  55.         {
  56.             textBox1.Text = string.Empty;
  57.         }
  58.         #endregion
  59.         #region RunTask
  60.         private Task RunTask(Action action)
  61.         {
  62.             return Task.Run(() =>
  63.             {
  64.                 try
  65.                 {
  66.                     action();
  67.                 }
  68.                 catch (Exception ex)
  69.                 {
  70.                     Log(ex.ToString());
  71.                     throw;
  72.                 }
  73.             });
  74.         }
  75.         private Task RunTask<T>(Action<T> action, T t)
  76.         {
  77.             return Task.Factory.StartNew(obj =>
  78.             {
  79.                 try
  80.                 {
  81.                     action((T)obj);
  82.                 }
  83.                 catch (Exception ex)
  84.                 {
  85.                     Log(ex.ToString());
  86.                     throw;
  87.                 }
  88.             }, t);
  89.         }
  90.         #endregion
  91.         #region cbxPrintSql_Click
  92.         private void cbxPrintSql_Click(object sender, EventArgs e)
  93.         {
  94.             _printSql = cbxPrintSql.Checked;
  95.         }
  96.         #endregion
  97.         #region 删除
  98.         private void button1_Click(object sender, EventArgs e)
  99.         {
  100.             RunTask(async () =>
  101.             {
  102.                 Log("删除 开始");
  103.                 await _db.GetSession().CreateSql("id>@Id", 20).DeleteByConditionAsync<SysUser>();
  104.                 Log("删除 完成");
  105.             });
  106.         }
  107.         #endregion
  108.         #region 批量修改
  109.         private void button2_Click(object sender, EventArgs e)
  110.         {
  111.             RunTask(async () =>
  112.             {
  113.                 List<SysUser> userList = await _db.GetSession().Queryable<SysUser>().Where(t => t.Id > 20).ToListAsync();
  114.                 Log("批量修改 开始 count=" + userList.Count);
  115.                 DateTime dt = DateTime.Now;
  116.                 ISession? session = null;
  117.                 try
  118.                 {
  119.                     foreach (SysUser user in userList)
  120.                     {
  121.                         user.Remark = "测试修改用户" + _rnd.Next(1, 10000);
  122.                         user.UpdateUserid = "1";
  123.                         user.UpdateTime = DateTime.Now;
  124.                     }
  125.                     session = await _db.GetSessionAsync();
  126.                     session.BeginTransaction();
  127.                     await session.UpdateAsync(userList);
  128.                     session.CommitTransaction();
  129.                 }
  130.                 catch
  131.                 {
  132.                     session?.RollbackTransaction();
  133.                     throw;
  134.                 }
  135.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  136.                 Log("批量修改 完成,耗时:" + time + "秒");
  137.             });
  138.         }
  139.         #endregion
  140.         #region 批量添加
  141.         private void button3_Click(object sender, EventArgs e)
  142.         {
  143.             RunTask(async () =>
  144.             {
  145.                 List<SysUser> userList = new List<SysUser>();
  146.                 for (int i = 1; i <= _count; i++)
  147.                 {
  148.                     SysUser user = new SysUser();
  149.                     user.UserName = "testUser";
  150.                     user.RealName = "测试插入用户";
  151.                     user.Password = "123456";
  152.                     user.CreateUserid = "1";
  153.                     user.CreateTime = DateTime.Now;
  154.                     userList.Add(user);
  155.                 }
  156.                 Log("批量添加 开始 count=" + userList.Count);
  157.                 DateTime dt = DateTime.Now;
  158.                 ISession? session = null;
  159.                 try
  160.                 {
  161.                     session = await _db.GetSessionAsync();
  162.                     session.BeginTransaction();
  163.                     await session.InsertAsync(userList);
  164.                     session.CommitTransaction();
  165.                 }
  166.                 catch
  167.                 {
  168.                     session?.RollbackTransaction();
  169.                     throw;
  170.                 }
  171.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  172.                 Log("批量添加 完成,耗时:" + time + "秒");
  173.             });
  174.         }
  175.         #endregion
  176.         #region 循环修改
  177.         private void button4_Click(object sender, EventArgs e)
  178.         {
  179.             RunTask(async () =>
  180.             {
  181.                 List<SysUser> userList = await _db.GetSession().Queryable<SysUser>().Where(t => t.Id > 20).ToListAsync();
  182.                 Log("循环修改 开始 count=" + userList.Count);
  183.                 DateTime dt = DateTime.Now;
  184.                 ISession? session = null;
  185.                 try
  186.                 {
  187.                     foreach (SysUser user in userList)
  188.                     {
  189.                         user.Remark = "测试修改用户" + _rnd.Next(1, 10000);
  190.                         user.UpdateUserid = "1";
  191.                         user.UpdateTime = DateTime.Now;
  192.                     }
  193.                     session = await _db.GetSessionAsync();
  194.                     session.BeginTransaction();
  195.                     foreach (SysUser user in userList)
  196.                     {
  197.                         await session.UpdateAsync(user);
  198.                     }
  199.                     session.CommitTransaction();
  200.                 }
  201.                 catch
  202.                 {
  203.                     session?.RollbackTransaction();
  204.                     throw;
  205.                 }
  206.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  207.                 Log("循环修改 完成,耗时:" + time + "秒");
  208.             });
  209.         }
  210.         #endregion
  211.         #region 循环添加
  212.         private void button5_Click(object sender, EventArgs e)
  213.         {
  214.             RunTask(async () =>
  215.             {
  216.                 List<SysUser> userList = new List<SysUser>();
  217.                 for (int i = 1; i <= _count; i++)
  218.                 {
  219.                     SysUser user = new SysUser();
  220.                     user.UserName = "testUser";
  221.                     user.RealName = "测试插入用户";
  222.                     user.Password = "123456";
  223.                     user.CreateUserid = "1";
  224.                     user.CreateTime = DateTime.Now;
  225.                     userList.Add(user);
  226.                 }
  227.                 Log("循环添加 开始 count=" + userList.Count);
  228.                 DateTime dt = DateTime.Now;
  229.                 ISession? session = null;
  230.                 try
  231.                 {
  232.                     session = await _db.GetSessionAsync();
  233.                     session.BeginTransaction();
  234.                     foreach (SysUser user in userList)
  235.                     {
  236.                         await session.InsertAsync(user);
  237.                     }
  238.                     session.CommitTransaction();
  239.                 }
  240.                 catch
  241.                 {
  242.                     session?.RollbackTransaction();
  243.                     throw;
  244.                 }
  245.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  246.                 Log("循环添加 完成,耗时:" + time + "秒");
  247.             });
  248.         }
  249.         #endregion
  250.         #region 查询
  251.         private void button6_Click(object sender, EventArgs e)
  252.         {
  253.             RunTask(async () =>
  254.             {
  255.                 Log("查询 开始");
  256.                 DateTime dt = DateTime.Now;
  257.                 for (int i = 0; i < 10; i++)
  258.                 {
  259.                     List<SysUser> userList = await _db.GetSession().Queryable<SysUser>()
  260.                              .Where(t => t.Id > 20 && t.RealName.Contains("%测试%"))
  261.                              .OrderByDescending(t => t.CreateTime)
  262.                              .OrderBy(t => t.Id).ToListAsync();
  263.                     Log("查询结果 count=" + userList.Count.ToString());
  264.                 }
  265.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  266.                 Log("查询 完成,耗时:" + time + "秒");
  267.             });
  268.         }
  269.         #endregion
  270.         #region 分页查询
  271.         private void button7_Click(object sender, EventArgs e)
  272.         {
  273.             Log("尚未实现");
  274.         }
  275.         #endregion
  276.         #region 并发查询
  277.         private void button8_Click(object sender, EventArgs e)
  278.         {
  279.             RunTask(() =>
  280.             {
  281.                 ThreadPool.SetMaxThreads(1000, 1000);
  282.                 ThreadPool.SetMinThreads(200, 200);
  283.                 Log("并发查询 开始");
  284.                 DateTime dt = DateTime.Now;
  285.                 List<Task> tasks = new List<Task>();
  286.                 for (int i = 1; i <= 1000; i++)
  287.                 {
  288.                     int index = i;
  289.                     Task task = RunTask(async () =>
  290.                     {
  291.                         List<SysUser> userList = await _db.GetSession().Queryable<SysUser>()
  292.                             .Where(t => t.Id > 20 && t.RealName.Contains("%测试%"))
  293.                             .OrderByDescending(t => t.CreateTime)
  294.                             .OrderBy(t => t.Id).ToListAsync();
  295.                         if (index % 50 == 0) Log("第" + index + "次查询结果 count=" + userList.Count);
  296.                     });
  297.                     tasks.Add(task);
  298.                 }
  299.                 Task.WaitAll(tasks.ToArray());
  300.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  301.                 Log("并发查询 完成,耗时:" + time + "秒");
  302.             });
  303.         }
  304.         #endregion
  305.         #region 并发插入
  306.         private void button9_Click(object sender, EventArgs e)
  307.         {
  308.             RunTask(() =>
  309.             {
  310.                 ThreadPool.SetMaxThreads(1000, 1000);
  311.                 ThreadPool.SetMinThreads(200, 200);
  312.                 List<SysUser> userList = new List<SysUser>();
  313.                 for (int i = 1; i <= _count; i++)
  314.                 {
  315.                     SysUser user = new SysUser();
  316.                     user.UserName = "testUser";
  317.                     user.RealName = "测试插入用户";
  318.                     user.Remark = "测试插入用户" + i;
  319.                     user.Password = "123456";
  320.                     user.CreateUserid = "1";
  321.                     user.CreateTime = DateTime.Now;
  322.                     userList.Add(user);
  323.                 }
  324.                 Log("并发插入 开始 count=" + userList.Count);
  325.                 DateTime dt = DateTime.Now;
  326.                 List<Task> tasks = new List<Task>();
  327.                 foreach (SysUser item in userList)
  328.                 {
  329.                     var task = RunTask(async user =>
  330.                     {
  331.                         await _db.GetSession().InsertAsync(user);
  332.                     }, item);
  333.                     tasks.Add(task);
  334.                 }
  335.                 Task.WaitAll(tasks.ToArray());
  336.                 string time = DateTime.Now.Subtract(dt).TotalSeconds.ToString("0.000");
  337.                 Log("并发插入 完成,耗时:" + time + "秒");
  338.             });
  339.         }
  340.         #endregion
  341.     }
  342. }
复制代码
Java MyBatis-Plus

插入和修改使用MyBatis-Plus,查询写了JdbcTemplate和MyBatis-Plus两个版本
Service层代码
  1. /**
  2. * @filename:SysUserServiceImpl 2022年6月7日
  3. * @project jdbc-template-test  V1.0
  4. * Copyright(c) 2018 sux Co. Ltd.
  5. * All right reserved.
  6. */
  7. package com.sux.jdbctest.service.impl;
  8. import com.sux.jdbctest.entity.SysUser;
  9. import com.sux.jdbctest.dao.SysUserDao;
  10. import com.sux.jdbctest.service.SysUserService;
  11. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  12. import org.springframework.stereotype.Service;
  13. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  14. import org.springframework.transaction.annotation.Transactional;
  15. import javax.annotation.Resource;
  16. import java.util.*;
  17. /**
  18. * @Description:TODO(用户表服务实现)
  19. * @version: V1.0
  20. * @author: sux
  21. */
  22. @Service
  23. public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUser> implements SysUserService {
  24.     @Resource(name = "transactionManager")
  25.     private DataSourceTransactionManager transactionManager;
  26.     /**
  27.      * 循环插入测试
  28.      */
  29.     @Transactional(rollbackFor = Exception.class)
  30.     public void loopInsert(List<SysUser> userList) {
  31.         for (SysUser user : userList) {
  32.             save(user);
  33.         }
  34.     }
  35.     /**
  36.      * 循环修改测试
  37.      */
  38.     @Transactional(rollbackFor = Exception.class)
  39.     public void loopUpdate(List<SysUser> userList) {
  40.         for (SysUser user : userList) {
  41.             updateById(user);
  42.         }
  43.     }
  44.     /**
  45.      * 批量插入测试
  46.      */
  47.     @Transactional(rollbackFor = Exception.class)
  48.     public void batchInsert(List<SysUser> userList) {
  49.         saveBatch(userList);
  50.     }
  51.     /**
  52.      * 批量修改测试
  53.      */
  54.     @Transactional(rollbackFor = Exception.class)
  55.     public void batchUpdate(List<SysUser> userList) {
  56.         updateBatchById(userList);
  57.     }
  58. }
复制代码
控制台测试代码
  1. package com.sux.jdbctest.task;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.sux.jdbctest.entity.SysUser;
  4. import com.sux.jdbctest.service.SysUserService;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.beans.factory.annotation.Qualifier;
  9. import org.springframework.boot.CommandLineRunner;
  10. import org.springframework.core.annotation.Order;
  11. import org.springframework.jdbc.core.BeanPropertyRowMapper;
  12. import org.springframework.jdbc.core.JdbcTemplate;
  13. import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
  14. import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
  15. import org.springframework.stereotype.Component;
  16. import java.util.*;
  17. @Order(1)
  18. @Component
  19. public class OnAppStart implements CommandLineRunner {
  20.     private static final Logger log = LoggerFactory.getLogger(OnAppStart.class);
  21.     @Autowired
  22.     private SysUserService sysUserService;
  23.     @Autowired
  24.     @Qualifier("primaryJdbcTemplate")
  25.     protected JdbcTemplate primaryJdbcTemplate;
  26.     private int _count = 10000;
  27.     @Override
  28.     public void run(String... args) throws Exception {
  29.         System.out.println("测试开始");
  30.         try {
  31.             QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
  32.             wrapper.last("limit 0,1");
  33.             List<SysUser> list = sysUserService.list(wrapper);
  34.             System.out.println("list.size()=" + list.size());
  35.             List<SysUser> list2 = primaryJdbcTemplate.query("select * from sys_user limit 0,1", new BeanPropertyRowMapper<>(SysUser.class));
  36.             System.out.println("list2.size()=" + list2.size());
  37.         } catch (Exception e) {
  38.             System.out.println("测试异常:");
  39.             e.printStackTrace();
  40.         }
  41.         System.out.println("预热完成");
  42.         Scanner scanner = new Scanner(System.in);
  43.         System.out.println("请输入操作 1:循环插入 2:循环修改 3:批量修改 4:使用JdbcTemplate查询 5:使用MyBatis-Plus查询 6:批量插入");
  44.         while (true) {
  45.             try {
  46.                 String ope = scanner.next();
  47.                 if (ope.equals("1")) {
  48.                     loopInsertTest();
  49.                 } else if (ope.equals("2")) {
  50.                     loopUpdateTest();
  51.                 } else if (ope.equals("3")) {
  52.                     batchUpdateTest();
  53.                 } else if (ope.equals("4")) {
  54.                     queryTestByJdbcTemplate();
  55.                 } else if (ope.equals("5")) {
  56.                     queryTestByMybatisPlus();
  57.                 } else if (ope.equals("6")) {
  58.                     batchInsertTest();
  59.                 }
  60.             } catch (Exception e) {
  61.                 System.out.println("测试异常:");
  62.                 e.printStackTrace();
  63.             }
  64.         }
  65.     }
  66.     /**
  67.      * 循环插入测试
  68.      */
  69.     public void loopInsertTest() {
  70.         List<SysUser> userList = new ArrayList<>();
  71.         for (int i = 1; i <= _count; i++) {
  72.             SysUser user = new SysUser();
  73.             user.setUserName("testUser");
  74.             user.setRealName("测试插入用户" + i);
  75.             user.setPassword("123456");
  76.             user.setCreateUserid("1");
  77.             user.setCreateTime(new Date());
  78.             userList.add(user);
  79.         }
  80.         System.out.println("循环添加 开始 count=" + userList.size());
  81.         long startTime = System.currentTimeMillis();
  82.         sysUserService.loopInsert(userList);
  83.         double time = (System.currentTimeMillis() - startTime) / 1000.0;
  84.         System.out.println("循环添加 完成,耗时:" + String.format("%.3f", time) + " 秒");
  85.     }
  86.     /**
  87.      * 循环修改测试
  88.      */
  89.     public void loopUpdateTest() {
  90.         QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
  91.         wrapper.and(qw -> qw.gt("id", 20));
  92.         List<SysUser> userList = sysUserService.list(wrapper);
  93.         for (SysUser user : userList) {
  94.             user.setRemark("测试修改用户" + String.format("%.0f", Math.random() * 10000));
  95.             user.setUpdateUserid("1");
  96.             user.setUpdateTime(new Date());
  97.         }
  98.         System.out.println("循环修改 开始 count=" + userList.size());
  99.         long startTime = System.currentTimeMillis();
  100.         sysUserService.loopUpdate(userList);
  101.         double time = (System.currentTimeMillis() - startTime) / 1000.0;
  102.         System.out.println("循环修改 完成,耗时:" + String.format("%.3f", time) + " 秒");
  103.     }
  104.     /**
  105.      * 批量插入测试
  106.      */
  107.     public void batchInsertTest() {
  108.         List<SysUser> userList = new ArrayList<>();
  109.         for (int i = 1; i <= _count; i++) {
  110.             SysUser user = new SysUser();
  111.             user.setUserName("testUser");
  112.             user.setRealName("测试插入用户" + i);
  113.             user.setPassword("123456");
  114.             user.setCreateUserid("1");
  115.             user.setCreateTime(new Date());
  116.             userList.add(user);
  117.         }
  118.         System.out.println("批量添加 开始 count=" + userList.size());
  119.         long startTime = System.currentTimeMillis();
  120.         sysUserService.batchInsert(userList);
  121.         double time = (System.currentTimeMillis() - startTime) / 1000.0;
  122.         System.out.println("批量添加 完成,耗时:" + String.format("%.3f", time) + " 秒");
  123.     }
  124.     /**
  125.      * 批量修改测试
  126.      */
  127.     public void batchUpdateTest() {
  128.         QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
  129.         wrapper.and(qw -> qw.gt("id", 20));
  130.         List<SysUser> userList = sysUserService.list(wrapper);
  131.         for (SysUser user : userList) {
  132.             user.setRemark("测试修改用户" + String.format("%.0f", Math.random() * 10000));
  133.             user.setUpdateUserid("1");
  134.             user.setUpdateTime(new Date());
  135.         }
  136.         System.out.println("批量修改 开始 count=" + userList.size());
  137.         long startTime = System.currentTimeMillis();
  138.         sysUserService.batchUpdate(userList);
  139.         double time = (System.currentTimeMillis() - startTime) / 1000.0;
  140.         System.out.println("批量修改 完成,耗时:" + String.format("%.3f", time) + " 秒");
  141.     }
  142.     /**
  143.      * 查询测试(使用JdbcTemplate)
  144.      */
  145.     public void queryTestByJdbcTemplate() {
  146.         System.out.println("使用JdbcTemplate查询 开始");
  147.         long startTime = System.currentTimeMillis();
  148.         MapSqlParameterSource param = new MapSqlParameterSource();
  149.         param.addValue("id", 20);
  150.         param.addValue("remark", "%测试%");
  151.         NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(primaryJdbcTemplate);
  152.         for (int i = 0; i < 10; i++) {
  153.             List<SysUser> list = namedParameterJdbcTemplate.query("select * from sys_user " +
  154.                     "where id > (:id) and remark like (:remark)" +
  155.                     "order by create_time desc, id asc", param, new BeanPropertyRowMapper(SysUser.class));
  156.             System.out.println("查询结果 count=" + list.size());
  157.         }
  158.         double time = (System.currentTimeMillis() - startTime) / 1000.0;
  159.         System.out.println("使用JdbcTemplate查询 完成,耗时:" + String.format("%.3f", time) + " 秒");
  160.     }
  161.     /**
  162.      * 查询测试(使用mybatis-plus)
  163.      */
  164.     public void queryTestByMybatisPlus() {
  165.         System.out.println("使用mybatis-plus查询 开始");
  166.         long startTime = System.currentTimeMillis();
  167.         QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
  168.         wrapper.and(qw -> qw.gt("id", 20))
  169.                 .like("remark", "%测试%")
  170.                 .orderByDesc("create_time")
  171.                 .orderByAsc("id");
  172.         for (int i = 0; i < 10; i++) {
  173.             List<SysUser> list = sysUserService.list(wrapper);
  174.             System.out.println("查询结果 count=" + list.size());
  175.         }
  176.         double time = (System.currentTimeMillis() - startTime) / 1000.0;
  177.         System.out.println("使用mybatis-plus查询 完成,耗时:" + String.format("%.3f", time) + " 秒");
  178.     }
  179. }
复制代码
测试结果

常规测试

Dapper.LiteSql net461


FreeSql net461


SqlSugar net461


Entity Framework


Fast.Framework net6

除了MySql.Data.dll还引用了MySqlConnector.dll (为什么net6?它不支持net framework)

Dapper.LiteSql net6


Java MyBatis-Plus

插入和修改使用MyBatis-Plus,查询写了JdbcTemplate和MyBatis-Plus两个版本
循环插入


批量插入


循环修改


批量修改


使用JdbcTemplate查询


使用MyBatis-Plus查询

MyBatis-Plus默认开启一级缓存?

结论

循环插入、循环修改、批量插入、批量修改,Java的一点也不慢,总体和C#的一个档次。
Java的查询似乎有缓存,MyBatis-Plus默认是开启一级缓存的,很快;JdbcTemplate应该是没有缓存的,相比C#的普遍在1秒内,是慢一些,但也没有慢太多。
并发查询

Dapper.LiteSql net461


FreeSql net461


SqlSugar net461


Entity Framework


Fast.Framework net6

除了MySql.Data.dll还引用了MySqlConnector.dll (为什么net6?它不支持net framework,环境不同,所以这个测试结果供参考,就不要计较了)

Dapper.LiteSql net6

(为了和Fast.Framework对比,确实慢,慢70%左右,可能是MySqlConnector.dll的功劳,它是真异步,只用MySql.Data.dll是假异步)

并发插入

Dapper.LiteSql net461


FreeSql net461


SqlSugar net461


Entity Framework


Fast.Framework net6

除了MySql.Data.dll还引用了MySqlConnector.dll (为什么net6?它不支持net framework)

Dapper.LiteSql net6

(为了和Fast.Framework对比)

写在最后

我不偏向任何ORM,有一说一。ORM的选择,性能固然重要,但性能差一点也不影响使用,主要是为了测试有没有硬伤,比如某个操作,一个ORM需要2秒,另一个ORM需要50秒,那50秒这个,慢了一个数量级还多,是不是有问题?再比如说某个测试,别的ORM,有耗时20秒的,有耗时30秒的,也有耗时70秒的,都问题不大,但有一个ORM,它报错了,是不是个问题?
这次并发测试,EF和EFCore我没有测试,因为我比较相信官方,可能它会慢一点,但因为用户量特别多,应该不会有硬伤。有兴趣的可以拿我的测试代码,稍微改一下测试测试EF和EFCore。
我自己写的LiteSql,算是个历史遗留问题,好几年前从上家公司的DBHelper一路改过来的,除非我把它完全删了,否则总想把它改好,这就需要测试,以保证质量。我因为写LiteSql,学了一些东西,技术上多多少少有进步,这就是意义。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

花瓣小跑

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表