1. 程式人生 > >Zoey.Dapper--Dapper擴展之把SQL語句放到文件中

Zoey.Dapper--Dapper擴展之把SQL語句放到文件中

start 重復 class 規範 and 負載平衡 security log mssq

介紹

不知道大家在用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方法
      • 實現了讀寫分離,當然 如果主庫和從庫連接字符串一樣就效果了
      • 這就是為什麽說支持多數據庫的原因了

結尾

該項目還是開始階段,只是個雛形,包括文件的命名都可能是不規範的.希望大家多給意見和建議.

Zoey.Dapper--Dapper擴展之把SQL語句放到文件中