Zoey.Dapper–Dapper擴充套件之把SQL語句放到檔案中

cnpm發表於2018-10-12

介紹

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

結尾

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

相關文章