介紹
不知道大家在用Dapper
的時候SQL語句是寫到哪的,目前看網上的例子都是寫到類裡面的.
此專案的目的是把SQL語句放到檔案(xml)中
目前只是初步版本,只是說明了意圖,後面會持續完善和優化
功能說明
- SQL 語句單獨存放在檔案(xml)中
- 支援配置多資料夾(暫不支援指定具體檔案)
- 實時監聽檔案變化
- 支援多資料庫(Dapper 本身就支援多資料,為什麼這裡說支援多資料呢?後面會講到)
- 支援讀寫分離(功能雖然有,但配置看起來不爽,後續應該會優化. 負載平衡演算法還未實現)
一起看看如何使用
-
首先我們需要一個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-query
和sql-command
節點來判斷的 name
屬性目前是所有檔案都不能重複
-
在
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") } }; });
說明:
- 大家也看到了,此處的配置很是繁瑣,上面我也說了,這裡應該要優化(但不緊急)
-
用的時候有兩種方式.
-
當我們沒呼叫
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
資訊,沒什麼特別的. -
下面我們看第二種:
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
方法 - 實現了讀寫分離,當然 如果主庫和從庫連線字串一樣就效果了
- 這就是為什麼說支援多資料庫的原因了
- 用此種方法必須在
-
結尾
該專案還是開始階段,只是個雛形,包括檔案的命名都可能是不規範的.希望大家多給意見和建議.