欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Zoey.Dapper--Dapper扩展之把SQL语句放到文件中

程序员文章站 2022-09-24 10:39:18
介绍 不知道大家在用 的时候 SQL 语句是写到哪的,目前看网上的例子都是写到类里面的. 此项目的目的是把 SQL 语句放到文件(xml)中 目前只是初步版本,只是说明了意图,后面会持续完善和优化 "GitHub 地址" 功能说明 SQL 语句单独存放在文件(xml)中 支持配置多文件夹(暂不支持指 ......

介绍

不知道大家在用dapper的时候sql语句是写到哪的,目前看网上的例子都是写到类里面的.

此项目的目的是把sql语句放到文件(xml)中

目前只是初步版本,只是说明了意图,后面会持续完善和优化

github 地址

功能说明

  • sql 语句单独存放在文件(xml)中
  • 支持配置多文件夹(暂不支持指定具体文件)
  • 实时监听文件变化
  • 支持多数据库(dapper 本身就支持多数据,为什么这里说支持多数据呢?后面会讲到)
  • 支持读写分离(功能虽然有,但配置看起来不爽,后续应该会优化. 负载平衡算法还未实现)

一起看看如何使用

  1. 首先我们需要一个xml文件,如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <sql xmlns="http://schema.zoey.com/sql" domain="default">
    <sql-query name="student.getstudentbyid">
        <text>
        <![cdata[
        select * from student where id = @id
        ]]>
        </text>
    </sql-query>
    
    <sql-command name="student.updatestudentbyid">
        <text>
        <![cdata[
        update student set age = @age,name = @name where id = @id
        ]]>
        </text>
    </sql-command>
    </sql>

    这里我们看下面几点:

    • sql节点上的domain属性.这里是指定数据库的连接字符串,后面会详细说明
    • 读写分离就是sql-querysql-command节点来判断的
    • name属性目前是所有文件都不能重复
  2. startup中的configureservices添加如下代码:

    //sql文件的读取和监视依赖 ifileprovider
     var physicalprovider = _env.contentrootfileprovider;
     services.addsingleton<ifileprovider>(physicalprovider);
    
     services.addzoeydappercore(options =>
     {
         //sql文件夹的路径  支持多个文件夹
         options.path = new list<string>() { "/config" };
         //监控文件的后缀(默认未 *.*)
         options.watchfilefilter = "*.xml";
         //该属性暂时没用
         options.startproxy = false;
     })
     //添加mssqlserver
     //这里说明一下 该方法是非必要的,下面会说
     .addmssqlserver(option =>
     {
         //添加数据库连接字符串
         //这里为什么没用配置文件读取,考虑到可能用到(secret manager)
         //后面可以提供直接从配置文件中读取
         option.databaseelements = new list<databaseelement>()
         {
             //参数1:唯一名称
             //参数2:连接字符串
             new databaseelement("testdb","data source=.;initial catalog=test;integrated security=true")
         };
         //此处就是上面提到的 domain 节点
         //每个domain对象有个唯一名称(xml文件domain的节点)
         //每个domain对象都有 master(主库) 和 slave(从库) 的名称(上面配置信息的名称)
         option.domainelements = new list<domainelement>()
         {
             new domainelement()
             {
                 //xml文件domain节点的名称
                 name = "default",
                 //主库和从库的名称(上面配置信息的名称)
                 //主库和从库可配多个(负载均衡算法暂没实现)
                 masterslaves = new masterslaves("testdb","testdb")
             }
         };
     });

    说明:

    • 大家也看到了,此处的配置很是繁琐,上面我也说了,这里应该要优化(但不紧急)
  3. 用的时候有两种方式.

    1. 当我们没调用addmssqlserver时,在controller中:

          public class homecontroller : controller
          {
              //注入isqlcontext
              private readonly isqlcontext _sqlcontext;
              public homecontroller(isqlcontext sqlcontext)
              {
                  this._sqlcontext = sqlcontext;
              }
      
              public iactionresult index()
              {
                  list<student> student;
                  //获取 student.getstudentbyid sql信息
                  var sql = _sqlcontext.getsqlelement("student.getstudentbyid");
                  using (var db = new sqlconnection("data source=.;initial catalog=test;integrated security=true"))
                  {
                      student = db.query<student>(sql.commandtext, new
                      {
                          id = 1
                      });
                  }
                  return view(student);
              }
      
              public iactionresult about()
              {
                  //获取 student.getstudentbyid sql信息
                  var sql = _sqlcontext.getsqlelement("student.updatestudentbyid");
                  using (var db = new sqlconnection("data source=.;initial catalog=test;integrated security=true"))
                  {
                      db.execute(sql.commandtext, new
                      {
                          age = new random().next(100),
                          name = "hello zoey!",
                          id = 1
                      });
                  }
                  return view();
              }
          }

      说明:此种方法只是单纯的获取sql信息,没什么特别的.

    2. 下面我们看第二种:

          public class homecontroller : controller
          {
              //注入 isqlcommand
              private readonly isqlcommand _sqlcommand;
              public homecontroller(isqlcommand sqlcommand)
              {
                  _sqlcommand = sqlcommand;
              }
      
              public iactionresult index()
              {
                  //此处直接执行 query 方法
                  var student = _sqlcommand.getsqlelement("student.getstudentbyid").query<student>(new
                  {
                      id = 1
                  });
      
                  return view(student);
              }
          }

      说明:

      • 用此种方法必须在 startup中调用addmssqlserver方法
      • 实现了读写分离,当然 如果主库和从库连接字符串一样就效果了
      • 这就是为什么说支持多数据库的原因了

结尾

该项目还是开始阶段,只是个雏形,包括文件的命名都可能是不规范的.希望大家多给意见和建议.