ShadowSql.net之sql拼寫神器
我正在開(kāi)發(fā)的一個(gè).net sql拼寫工具(SqlBuilder),也可以算是ORM,命名為ShadowSql
本工具的作用就是幫碼農(nóng)拼寫sql,對(duì)標(biāo)開(kāi)源項(xiàng)目SqlKata。
在項(xiàng)目里面直接拼寫sql很容易出錯(cuò),是件很Low的事情,所以我們需要ORM工具。
但是有些ORM很重,很擔(dān)心造成性能問(wèn)題,這就是開(kāi)發(fā)本工具的出發(fā)點(diǎn).
本工具很小、不依賴第三方包,不使用反射,應(yīng)該支持AOT原生編譯,不過(guò)我還沒(méi)測(cè)試。
本工具最大的特點(diǎn)就是性能好,省內(nèi)存,拼接sql從頭到尾只使用一個(gè)StringBuilder。
跨平臺(tái)、可擴(kuò)展、支持多種數(shù)據(jù)庫(kù),可以自定義數(shù)據(jù)庫(kù)方言,支持net7.0;net8.0;net9.0;netstandard2.0;netstandard2.1。
本工具最適合搭配Dapper使用,所以附帶了一個(gè)Dapper擴(kuò)展。當(dāng)然直接搭配ado.net也是可以的。
sql操作用的最多也是最復(fù)雜的就是查詢,本工具包含兩套查詢模式:sql模式和邏輯模式。
一、先介紹sql查詢模式
1、支持按原生sql進(jìn)行查詢,示例如下:
var query = db.From("Users") .ToSqlQuery() .Where("Id=@Id", "Status=@Status");
sql: SELECT * FROM [Users] WHERE Id=@Id AND Status=@Status
2、支持按邏輯查詢
var query = new UserTable() .ToSqlQuery() .Where(Id.EqualValue(100));
sql: SELECT * FROM [Users] WHERE [Id]=100
3、支持GroupBy
var table = db.From("Users"); var groupBy = table.ToSqlQuery() .ColumnEqualValue("Age", 20) .GroupBy("CityId") .Having(g => g.Aggregate("MAX", "Level").GreaterValue(9));
sql: SELECT * FROM [Users] WHERE [Age]=20 GROUP BY [CityId] HAVING MAX([Level])>9
4、支持聯(lián)表
var employees = db.From("Employees"); var departments = db.From("Departments"); var joinOn = employees.SqlJoin(departments) .On(static (t1, t2) => t1.Field("DepartmentId").Equal(t2.Field("Id"))); var joinTable = joinOn.Root .Where(join => join.From("t2").Field("Manager").EqualValue("CEO"));
sql: SELECT * FROM [Employees] AS t1 INNER JOIN [Departments] AS t2 ON t1.[DepartmentId]=t2.[Id] WHERE t2.[Manager]='CEO'
二、邏輯模式
以上功能邏輯模式大多都支持,邏輯模式是按And、Or來(lái)查詢的。沒(méi)有where、having、on等關(guān)鍵字
邏輯模式不支持按原生sql查詢,當(dāng)然封裝為邏輯對(duì)象就可以了,但不推薦這么做。
所謂邏輯就是與、或、非運(yùn)算。
Sql模式也支持邏輯對(duì)象,從這個(gè)層面上說(shuō)sql模式功能更全,sql模式查詢對(duì)象就是包含一個(gè)復(fù)合邏輯對(duì)象+Sql查詢對(duì)象。
邏輯模式一般執(zhí)行速度更快、內(nèi)存消耗更少。
1、單表查詢
var query = db.From("Users") .ToQuery() .And(_id.Equal()) .And(_status.Equal("Status"));
var query = db.From("Users") .ToOrQuery() .Or(_id.Equal()) .Or(_status.Equal("Status"));
SELECT * FROM [Users] WHERE [Id]=@Id AND [Status]=@Status
SELECT * FROM [Users] WHERE [Id]=@Id OR [Status]=@Status
2、GroupBy
var groupBy = table.ToQuery() .And(Age.EqualValue(20)) .GroupBy("CityId") .And(Level.Max().GreaterValue(9));
sql: SELECT * FROM [Users] WHERE [Age]=20 GROUP BY [CityId] HAVING MAX([Level])>9
3、聯(lián)表
CommentTable c = new("c"); PostTable p = new("p"); var joinOn = c.Join(p) .And(c.PostId.Equal(p.Id)); var query = joinOn.Root .And(c.Pick.Equal()) .And(p.Author.Equal())
sql: SELECT * FROM [Comments] AS c INNER JOIN [Posts] AS p ON c.[PostId]=p.[Id] where c.[Pick]=@Pick AND p.[Author]=@Author
篇幅有限,還有很多功能沒(méi)法在這里一一列舉,歡迎大家去探索,抽出時(shí)間我也會(huì)再發(fā)新文章來(lái)做更詳細(xì)的介紹。
三、兩種模式與SqlKata對(duì)比速度都更快,消耗內(nèi)存也更少

更多信息可以到github上查詢,或下載代碼自己測(cè)試一下
四、源碼托管在github上
倉(cāng)庫(kù)地址: https://github.com/donetsoftwork/Shadow
如果大家喜歡請(qǐng)動(dòng)動(dòng)您發(fā)財(cái)?shù)男∈质謳兔c(diǎn)一下Star。
有什么建議也可以反饋給我,該項(xiàng)目還在開(kāi)發(fā)中,還可能會(huì)增加更多有趣的功能。
而且我還計(jì)劃為這個(gè)工具再開(kāi)發(fā)一個(gè)精簡(jiǎn)版本,以求更好的性能。
posted on 2025-04-02 22:32 xiangji 閱讀(2253) 評(píng)論(25) 收藏 舉報(bào)
浙公網(wǎng)安備 33010602011771號(hào)