• SqlSugar轻量ORM


     

    蓝灯软件数据股份有限公司项目,代码开源。

    SqlSugar是一款轻量级的MSSQL ORM ,除了具有媲美ADO的性能外还具有和EF相似简单易用的语法。

     

    学习列表

      0、功能更新

     1、SqlSugar基础应用

     2、使用SqlSugar处理大数据

     3、使用SqlSugar实现Join  待更新

     4、使用SqlSugar实现分页+分组+多列排序 待更新

     5、节点故障如何进行主从调换

    一、介简

    优点:

    1、优越的性能,查询使用  reflection.emit 创建IL语言+委托绑定 然后对该对象进行 cache ,datareader直接赋值给cache对象,高性能拉姆达解析,总体性能媲美 ADO.NET ,查询速度稍慢于datareader但稍快于datatable

    2、大量语法糖,拉姆达表达示筛选,新颖的多表查询 ,方便的分页等

    3、支持NOLOCK查询,提高性能

    4、支持事务

    5、内置实体类生成函数,无需使用第三方代码生成器

    6、简单好用、例子齐全有问必答。

    缺点:

    目前只支持MSSQL,以后会全面发展 

    组成:

    sqlSugar是由sqlSugarClientr提供统一调用模式 ,sqlSugarClientr是由5个部分组成

    1、自身函数 

    2、实体生成

    3、单表查询

    4、多表查询

    5、基类函数

    如图:

     

    二、使用教程

    查询

     

    1、单表或者单视图查询:

    通过调用 db.Queryable() 的相关扩展函数 轻松搞定单表查询

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    using (SqlSugarClient db = new SqlSugarClient(connStr))//开启数据库连接
            {
     
                      
                       //查询所有
                        var student = db.Queryable<Student>().ToList();
     
                        //查询单条
                        var single = db.Queryable<Student>().Single(c => c.id == 1);
     
                        //取10-20条
                        var page1 = db.Queryable<Student>().Where(c => c.id > 10).OrderBy("id").Skip(10).Take(20).ToList();
                        //上一句的简化写法,同样取10-20条
                        var page2 = db.Queryable<Student>().Where(c => c.id > 10).OrderBy("id").ToPageList(2, 10);
     
                        //查询条数
                        var count = db.Queryable<Student>().Where(c => c.id > 10).Count();
     
                        //从第2条开始以后取所有
                        var skip = db.Queryable<Student>().Where(c => c.id > 10).OrderBy("id").Skip(2).ToList();
     
                        //取前2条
                        var take = db.Queryable<Student>().Where(c => c.id > 10).OrderBy("id").Take(2).ToList();
     
                        // Not like
                        var notLike = db.Queryable<Student>().Where(c => !c.name.Contains("a".ToString())).ToList();
     
                        // 可以在拉姆达使用 ToString和 Convert,比EF出色的地方
                        var convert1 = db.Queryable<Student>().Where(c => c.name == "a".ToString()).ToList();
                        var convert2 = db.Queryable<Student>().Where(c => c.id == Convert.ToInt32("1")).ToList();//
                        var convert3 = db.Queryable<Student>().Where(c => DateTime.Now > Convert.ToDateTime("2015-1-1")).ToList();
                        var convert4 = db.Queryable<Student>().Where(c => DateTime.Now > DateTime.Now).ToList();
     
                        //支持字符串Where 让你解决,更复杂的查询
                        var student12 = db.Queryable<Student>().Where(c => 1 == 1).Where("id>@id",new{id=1}).ToList();
     
     

      

    1
    2
    3
    //存在记录反回true,则否返回false
     bool isAny100 = db.Queryable<Student>().Any(c => c.id == 100);
     bool isAny1 = db.Queryable<Student>().Any(c => c.id == 1);

    2、单表高级查询

    根据条件查询并分页 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    /// <summary>
          /// 根据条件查询并且分页
          /// </summary>
          /// <param name="name"></param>
          /// <param name="sex"></param>
          /// <returns></returns>
          public static List<Student> GetStudent(string name, string sex, int pageIndex, int pageSize, string orderFileds,out int pageCount)
          {
              using (SqlSugarClient db = SugarDao.GetInstance())
              {
                  var qable = db.Queryable<Student>();
                  if (!string.IsNullOrEmpty(name))
                  {
                      qable = qable.Where(it => it.name.Contains(name));
                  }
                  if (!string.IsNullOrEmpty(sex))
                  {
                      qable = qable.Where(it => it.sex == sex);
                  }
                  if (!string.IsNullOrEmpty(orderFileds))//无需担心注入
                  {
                      qable = qable.OrderBy(orderFileds);
                  }
                  pageCount = qable.Count();
                  return qable.ToPageList(pageIndex, pageSize);
              }
          }

      

     新容器转换

    1
    2
    3
    4
    5
    6
    7
    public List<classNew> GetSelectList(int id)
    {
        using (SugarDao db = new SugarDao())
        {
            return db.Queryable<Student>().Where(c=>c.id<10).Select(c => new classNew { newid = c.id, newname = c.name,xx_name=c.name }).ToList();//不支持匿名类转换,也不建议使用
        }
    }

    分组查询

    1
    2
    3
    4
    5
    6
    7
    public List<SexTotal> GetSexTotal()
           {
               using (SugarDao db = new SugarDao())
               {
                   return db.Queryable<Student>().Where(c => c.id < 20).GroupBy("sex").Select<Student, SexTotal>("Sex,Count=count(*)").ToList();
               }
           }
    1
    SELECT Sex,Count=count(*)  FROM Student  WHERE 1=1  AND  (id < 20)    GROUP BY Sex --生成结果

      

      

     3、多表查询:

    说到多表查询在众多ORM中无论是性能还是功能上都不满意,或者说还不如用SQL,下面是我的创意,放弃了强类型写法,让代码更接近SQL语句编写,让SQL完全可控,也解决了OMR多表的性能问题。

    还有ORDERBY、GROUPBY和APPLY等,例子中就不介绍了。

    拿EF来比较一下:

    EF查询:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var reval = (from s in db.Student
                                   join sc in db.School on s.sch_id equals sc.id
                                   join sb in db.Subject on s.id equals sb.sid
                                   into ssb
                                   from sb2 in ssb.DefaultIfEmpty()
                                   select new {
                                   s.id,
                                   s.name,
                                   s.sch_id,
                                   s.sex
                                   }).Where(c=>c.id>1).Where(c=>c.id>2).OrderBy(c=>c.id).ThenByDescending(c=>c.name).Skip(10).Take(10).ToList();

    SqlSugar查询:

    1
    2
    3
    4
    db.Sqlable().Form<Student>("s")
                      .Join<School> ("sc", "sc.id", "s.sch_id", JoinType.INNER)
                      .Join<subject>("sb", "sb.sid", "s.id", JoinType.LEFT).Where("s.id>@id1").Where("s.id>@id2")
                      .SelectToPageList<Models.Student>("s.*", "s.id asc,s.name desc", 2, 10, new { id1=1,id2=2 });

    更多的SqlSugar查询:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //表名是字符串写法
    List<School> dataList = db.Sqlable()
       .Form("school", "s")
       .Join("student", "st", "st.id", "s.id", JoinType.INNER)
       .Join("student", "st2", "st2.id", "st.id", JoinType.LEFT).Where("s.id>100 and s.id<@id").SelectToList<School>("st.*", new { id = 1 });
     
    //多表分页
    List<School> dataPageList = db.Sqlable()
        .Form<school>("s")
        .Join<student>("st", "st.id", "s.id", JoinType.INNER)
        .Join<student>("st2", "st2.id", "st.id", JoinType.LEFT).Where("s.id>100 and s.id<100").SelectToPageList<School>("st.*", "s.id", 1, 10);

    子查询加动态拼接

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public List<Student> GetStudent(int id, string name)
           {
               int pageCount = 0;
               using (var db = SugarDao.GetInstance())
               {
                   //Form("Student","s")语法优化成 Form<Student>("s")
                   var sable = db.Sqlable().Form<Student>("s").Join<School>("l", "s.sch_id", "l.id", JoinType.INNER);
                   if (!string.IsNullOrEmpty(name))
                   {
                       sable = sable.Where("s.name=@name");
                   }
                   if (!string.IsNullOrEmpty(name))
                   {
                       sable = sable.Where("s.id=@id or s.id=100");
                   }
                   if (id > 0) {
                       sable = sable.Where("l.id in (select top 10 id from school)");//where加子查询
                   }
                   //参数
                   var pars = new { id = id, name = name };
                   pageCount = sable.Count(pars);
                   return sable.SelectToList<Student>("s.*", pars);
               }
           }

      

     4、 使用SQL或者存储过程查询:

     为了兼容上面满足不了的情况所以也写了这么个函数以便应急之需

      

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var School = db.SqlQuery<School>("select * from School");
     
                        //获取id
                        var id = db.SqlQuery<int>("select top 1 id from School").Single();
     
                        //存储过程
                        //var spResult = db.SqlQuery<school>("exec sp_school @p1,@p2", new { p1=1,p2=2 });
                          
                        //无返回值
                        db.ExecuteCommand(sql);

      

    添加

       

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    using (SqlSugarClient db = new SqlSugarClient(connStr))//开启数据库连接
    {
     
                School s = new School()
                {
                    name = "蓝翔"
                };
     
                //插入单条
                var id2 = Convert.ToInt32(db.Insert(s));
     
                //插入多条
                List<School> sList = new List<School>();
                sList.Add(s);
                var ids = db.InsertRange(sList);
     }

      

    修改

      

    1
    2
    3
    4
    //指定列更新
    db.Update<School>(new { name = "蓝翔2" }, it => it.id == id);
    //整个实体更新,注意主键必需为实体类的第一个属性
    db.Update<School>(new School { id = id, name = "蓝翔2" }, it => it.id == id);

      

    删除

     

    1
    2
    3
    4
    5
    6
    7
    db.Delete<School>(id);//注意主键必需为实体类的第一个属性
    db.Delete<School>(it => it.id > 100);
    db.Delete<School>(new string[] { "100", "101", "102" });
       
     db.FalseDelete<school>("is_del", 100);//假删除
     //等同于 update school set is_del=0 where id in(100)<br>
     db.FalseDelete<school>("is_del", it=>it.id==100);

    更多底层函数

       

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    db.ExecuteCommand(sql);
     
     db.GetDataTable(sql);
     db.GetList<Student>(sql);
     db.GetSingle<Student>(sql + " where id=1");
     using (SqlDataReader read = db.GetReader(sql)) { }  //事务中一定要释放DataReader
     
     db.GetScalar(sql);
     db.GetString(sql);
     db.GetInt(sql);

      

    实体生成

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    using (SqlSugarClient db = new SqlSugarClient(connStr))//开启数据库连接
     {
     
                      //根据当前数据库生成所有表的实体类文件 (参数:SqlSugarClient ,文件目录,命名空间)
                        db.ClassGenerating.CreateClassFiles(db,Server.MapPath("~/Models"),"Models");
                        //根据表名生成实体类文件
                        db.ClassGenerating.CreateClassFilesByTableNames(db, Server.MapPath("~/Models"), "Models" , "student","school");
     
                        //根据表名生成class字符串
                        var str = db.ClassGenerating.TableNameToClass(db, "Student");
     
                        //根据SQL语句生成class字符串
                        var str2 = db.ClassGenerating.SqlToClass(db, "select top 1 * from Student", "student");

      

    事务

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    using (SqlSugarClient db = new SqlSugarClient(connStr))//开启数据库连接
    {
       try{
           //开启事务,可以不使用事务,也可以使用多个事务
            db.BeginTran();
             
            //sq1
            //sql2
            //sql3
     
        }catch (Exception ex){
           //回滚事务
           db.RollbackTran();
           throw ex;
        }
     
    }//关闭数据库连接

    无锁查询

     

      当IsNoLock设为True时,查询生成的SQL语句表名的后面都会带有With(Nolock)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    using (SqlSugarClient db = new SqlSugarClient(connStr))//开启数据库连接
    {
              db.IsNoLock = true;
              //sql xxx with(nolock)
              db.IsNoLock = false;
              //sql xxx
              //sql xxx
              db.IsNoLock = true;
              //sql xxx with(nolock)
     
    }//关闭数据库连接

      

     

    支持多库切换的写法

     

    定义一个sugarDao类来扩展SqlSugar

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /// <summary>
      /// 扩展SqlSugarClient
      /// </summary>
      public class SugarDao
      {
          //禁止实例化
          private SugarDao() {
     
          }
          public static SqlSugarClient GetInstance()
          {
              string connection = "Server=.;uid=sa;pwd=sasa;database=SqlSugarTest"; //这里可以动态根据cookies或session实现多库切换
              return new SqlSugarClient(connection);
          }
      }

      

    使用无需传入connectionString

    1
    2
    3
    4
    5
    6
    7
    public School GetSingleSchool(int id)
      {
          using (SqlSugarClient db = SugarDao.GetInstance())
          {
              return db.Queryable<School>().Single(c => c.id == id);
          }
      }

      

     

    三、性能测试:

                 10000次

     

     1000次

    10000次

    .net4.52+EF 6.0+SQL12  以洗耻辱  

    .NET Framework 4.52+ sql12 +EF6.0 ,EF性能明显上去了,就让它当个冠军吧,我也不去测试了,微软的东西升级后性能无需质疑,在多表查询和添删改方面综合下来也基本平手。

    SqlSugar追求的是轻量、上手快、简单易用对SQL的可控性,也希望你能喜欢或者提出您宝贵意见。

     

    V1.0源码下载地址:

    http://pan.baidu.com/s/1bnmAXjh

    V1.2源码下载地址:

    http://pan.baidu.com/s/1jGENyQi

    更改内容:

    contains查询BUG,SQL拼接BUG

    V1.3源码下载地址:

    http://pan.baidu.com/s/1kTrRbmR

    更改内容:

    添加 queryable/sqlable to dataTable  

    CACHE BUG修复

    支持  int?类型这类 nullable类型

    此版本稳定,多家公司正在使用

    有一点需要声名如果主键不是identity需要写成 insert(obj,false)这不是BUG

     主键位置在类中可以任意放无需放第一个

    V1.5源码下载地址: 

    http://pan.baidu.com/s/1pJ8F0dt

    更改内容:

    1、代码结构优化

    2、删除语法需要注意 

     以前删除

     db.Delete<School>(new string[] { "100", "101", "102" });

    需要改成下面这种写法

     db.Delete<School,string>(new string[] { "100", "101", "102" });

    3、添加批量更新 

    db.Update<School, string>(new { name = "蓝翔2" },new string []{"1","2"});

  • 相关阅读:
    [android] add system services
    java layer调用native层的android_media_AudioTrack_get_min_buff_size()确定audio track buffer的min size
    [转]linux 系统 errno.h错误码
    java static final泛型类对象
    Linux--信号阻塞与屏蔽
    02-CSS基础与进阶-day2_2018-08-27-20-34-56
    02-CSS基础与进阶-day2_2018-08-27-20-15-54
    69期-Java SE-001_Java概述-001-002
    02-CSS基础与进阶-day1-录像296
    02-CSS基础与进阶-day1-录像295
  • 原文地址:https://www.cnblogs.com/zhangxiaolei521/p/5657328.html
Copyright © 2020-2023  润新知