zoukankan      html  css  js  c++  java
  • net下的高性能轻量化半自动orm+linq的《SqlBatis》

    一、项目介绍

    该项目内置单表linq操作,xml动态sql解析,词法分析,类型映射等功能。

    1. SqlMapper,用来处理sql与数据库操作,它设计的目标是支持mysql,sqlserver,sqllite,pgsql等.

    2. TypeMapper用于完成将数据库的字段类型映射到C#类型,内部定义了类型转换函数和转换规则.

    3. TypeConvert用于完成数据库记录到C#类型的转换。通过IL动态创建IDataReader对象到C#实体类的转换函数和将C#对象解构成Key-value的函数.

    4. ExpressionContext是一个轻量的词法分析器,用于将字符串表达式生成C#表达式,进而生成委托.

    5. XmlResovle用于解析xml配置,如果你的项目仅需要xml动态解析功能你完全可以下载我的源码进行改进(它在github中开源),半自动意味着超高的性能
    6. https://github.com/1448376744/SqlBatis

    二 、词法分析器

    该类型的实例是线程安全的,可复用的。它的设计及其简单,功能也很有限,但是对于我们的需求足够了. 它的实现逻辑如下:

    var expr = "(Age!=null) && (Name=='zs')";
    /**
    
    1.通过正则匹配出每一个括号,因此你必须手动的给每个二元表达式加括号,它无法识别运算符的优先级.
    $1 = (Age!=null)
    $2 = (Name=='zs')
    $3 = $1 && $2
    
    2.创建参数类型
    Expression.Parameter(typeof(T), "p");
    
    3.逐个创建二元表达式
    Expression.MakeUnary(ExpressionType.Convert, expr, type)
    ...
    */
    var context = new ExpressionContext();
    //Age必须是可以为null的类型:int?
    var result = context.Create<Student>("(Age != null) && (Name=='zs')");
    var flag= result.Func(new Student { Age =(int?) 1, Name = "zs" });
    /**
    常见错误:
    1. (Age != null) && Name=='zs'
    缺少括号 2. public class Student{ public int Age{get;set;} public string Name {get;set;}}
    Age必须是int?类型 */

      

    ExpressionContext

    var context = new ExpressionContext();
    var result = context.Create<Student>("(Age!=null)&&(Name=='zs')");
    var expr = result.LambdaExpression;
    Func<Student, bool> func = result.Func;
    var flag = func(new Student { Age = 1, Name = "zs" });
    

      

    三、XML解析

    <?xml version="1.0" encoding="utf-8" ?>
    
    <commands namespace="sutdent">
    
      <!--
        框架只定义了if,variable,where等标签
        insert,select可以随意,并没有实际意义
      -->
      <variable id="columns">
        Id,Age,Name
      </variable>
    
      <select id="list-dynamic">
        select ${columns} from student
        <where>
          <if test="Id!=null" value="id=@Id"/>
        </where>
        limit 0,1   
      </select>
    
      <insert id="add">
        insert into student(name,age)values(@Name,@age)
      </insert>
    
    </commands>
     
    //解析sql var resovle = new XmlResovle(); resovle.Load(@"E:SqlBatisSqlBatis.Test", "*.xml"); //普通sql var sql1 = resovle.Resolve("namespace.id"); //动态sql var sql2 = resovle.Resolve("namespace.id",new { Id=(int?)null,Age=2});

     四、配置DbContext

      方式1

    public class MysqlDbConrext : DbContext
    {
        public IDbQuery<Student> Students { get => new DbQuery<Student>(this); }
        private static readonly IXmlResovle resovle;
        static MysqlDbConrext()
        {
    //不要为每一个DbContext加载配置 resovle = new XmlResovle(); resovle.Load(@"E:SqlBatisSqlBatis.Test","*.xml"); } protected override void OnLogging(string message, object parameter = null, int? commandTimeout = null, CommandType? commandType = null) { } protected override DbContextBuilder OnConfiguring(DbContextBuilder builder) { ILoggerFactory factory = LoggerFactory.Create(b => { b.AddConsole(); b.AddDebug(); b.SetMinimumLevel(LogLevel.Debug); }); builder.Connection = new MySql.Data.MySqlClient.MySqlConnection("server=127.0.0.1;user id=root;password=1024;database=test;"); builder.XmlResovle = null; return builder; } public MysqlDbConrext() { Students = new DbQuery<Student>(this); } }

     方式2

    var db = new DbContext(new DbContextBuilder()
    { 
        DbContextType=DbContextType.Mysql,
        ...
    });
    

    五、XML+Linq

    using (var db = new SqlDbContext())
    {
        //linq
        var row = db.Students.Delete();
        var (list, count) = db.Students
            .Page(1, 2)
            .SelectMany();
        //dynamic
        var p = new { Id = (int?)null, Name = "zs" };
        var dylist = db.Students
           .Where(a => a.Id == 1, p.Id != null)
           .Where(a => a.Name == p.Name, p.Name != null)
           .SelectMany();
        //xml
        row = db.From("sutdent.add", new Student()
        {
            Age = 20,
            IsDelete = true,
            Name = "xml"
        }).ExecuteNonQuery();
        //dynamic:注意由于内部会缓存表达式创建的委托,因此同一个动态的xml命令不能用不同的参数去获取它
        //建议如果获取的xml命令是动态的,则应保证整个项目只有一次获取的代码,或者使用同一种参数类型
        row = db.From("stutdent.list-dynamic", p).ExecuteNonQuery();
        //多结果集查询,xml方式同样支持
        using (var muti = db.ExecuteMultiQuery("select * from student;select count(1) from student;"))
        {
            //第一个结果集
            var list = muti.GetList<Student>();
            //第二个结果集
            var count = muti.Get<int>();
        }
    }
    

      

      

      

     

  • 相关阅读:
    重定向丶管道丶参数传递
    zabbix监控redis
    zabbix监控mysql
    playbook
    zabbix通过jvm监控tomcat
    zabbix监控tcp状态
    部署centos6
    自动选择profile
    java jvm学习笔记十二(访问控制器的栈校验机制)
    java jvm学习笔记十一(访问控制器)
  • 原文地址:https://www.cnblogs.com/chaeyeon/p/12205267.html
Copyright © 2011-2022 走看看