OSS.Core基于Dapper封裝(表達式解析+Emit)倉儲層的構(gòu)思及實現(xiàn)

    最近趁著不忙,在構(gòu)思一個搭建一個開源的完整項目,至于原因以及整個項目框架后邊文章我再說明。既然要起一個完整的項目,那么數(shù)據(jù)倉儲訪問就必不可少,這篇文章我主要介紹這個新項目(OSS.Core)中我對倉儲層的簡單思考和實現(xiàn)過程(當前項目還處在搭建階段),主要集中在以下幾個方面:

10年積累的成都網(wǎng)站制作、做網(wǎng)站經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認識你,你也不認識我。但先網(wǎng)站設(shè)計后付款的網(wǎng)站建設(shè)流程,更有利通免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

1. 數(shù)據(jù)倉儲層的需求

2. ORM框架選擇

3. OSS.Core倉儲層設(shè)計實現(xiàn)

4. 調(diào)用示例

   下邊的實現(xiàn)部分中可能需要你對.NET的 泛型,委托,擴展,表達式等有一個基礎(chǔ)了解。正是因為這些語言特性,方便我們對操作共性的抽取統(tǒng)一。

一. 數(shù)據(jù)倉儲層需求

既然是一個完整的項目,數(shù)據(jù)訪問是其最基本的部分,同時,數(shù)據(jù)訪問也是整個項目最容易出現(xiàn)瓶頸的地方。在我的劃分中,其承擔的角色是負責整個數(shù)據(jù)的輸入輸出,不僅僅是針對單數(shù)據(jù)庫(有時甚至多庫),有時還需要完成一級緩存的實現(xiàn),給邏輯層提供最基礎(chǔ)的數(shù)據(jù)支撐。

 業(yè)務(wù)永遠是在變化的,那么項目也要具備快速演進的能力,所以我希望數(shù)據(jù)層能夠保持相對的簡單,在結(jié)構(gòu)上盡量減少復雜的耦合查詢,在性能上盡量減少不必要的消耗,例如反射的大量使用。同時針對每個業(yè)務(wù)對象完成數(shù)據(jù)庫層面基本的CRUD統(tǒng)一封裝實現(xiàn)。如果有需要的時候還能在最少的改動下加入緩存的更新。(對于如何實現(xiàn)不同模塊不同緩存存儲策略,像redis,Memcached會在后邊文章介紹)

同時,對于一個稍微有點規(guī)模的項目來說,解決數(shù)據(jù)庫訪問的最快速做法就是實現(xiàn)讀寫分離,所以,我希望這個框架能夠在一開始在底層就實現(xiàn)了讀寫分離的支持,以避免后期再重頭對業(yè)務(wù)代碼的大量修改。

二. ORM 框架選擇

當然,如果為了簡單和性能,直接ADO.NET連接理論上來說是比較高效的做法,不過這樣會造成大量的重復操作邏輯代碼,同時也會造成代碼的散亂,增加維護復雜度。作為技術(shù)人員,不僅需要解決業(yè)務(wù)問題提高效率,同時也要提高自己的效率,所以我會選擇一個ORM框架來完成部分基礎(chǔ)工作。

當前在.NET體系下,開源的ORM框架很多,如:Entityframework,NHibernate,iBATIS.NET,Dapper等等,各有特色,基于前面我說的,保證效率的同時,兼顧簡單還能最大程度減少性能的損耗,并且提供.net standard標準庫下的支持。這里對比之后我選擇Dapper這個半自動化的ORM作為倉儲層的基礎(chǔ)框架,選擇原因如下:

1. 其結(jié)構(gòu)簡單,整個封裝主要集中Dapper.cs文件中,體積很小

      2. 封裝功能簡單強大,對原生SQL的支持上很靈活

這點幾乎完勝其他框架,無需任何多余的設(shè)置,同時基本上你可調(diào)用所有原生ADO.NET的功能,sql語句完全自己掌控,卻又無需關(guān)心command的參數(shù)賦值,以及結(jié)果實體轉(zhuǎn)換等。

3. 性能上的高效

很多ORM的實體映射通過反射來完成,這點上Dapper再次展現(xiàn)其魅力,在Commond參數(shù)賦值,以及實體轉(zhuǎn)換等關(guān)鍵模塊,使用了Reflection.Emit功能,間接實現(xiàn)了MSIL編譯層面的賦值實現(xiàn),之所以說間接,是因為其本身代碼還需要編譯器生成IL代碼。在運行時根據(jù)類型屬性動態(tài)創(chuàng)建賦值委托方法。

 

三. OSS.Core倉儲層設(shè)計實現(xiàn)

 通過Dapper可以實現(xiàn)在數(shù)據(jù)庫訪問部分一層簡單的封裝,不過我依然需要手動編寫不少的sql語句,同時還要進行參數(shù)化的處理,包括數(shù)據(jù)的讀寫分離等。那么這些功能的實現(xiàn)我將在OSS.Core.RepDapper中完成,為了方便理解,先貼出一個簡單的封裝后的方法調(diào)用傳輸流程:

OSS.Core基于Dapper封裝(表達式解析+Emit)倉儲層的構(gòu)思及實現(xiàn)

在這個圖里展示一個簡單的方法調(diào)用流程,圍繞這張圖的幾個核心部分,我分別介紹下:

  1. 接口設(shè)計

因為我希望這個是完整的示例項目,所以后邊希望能夠兼容不同數(shù)據(jù)庫,因此對外的倉儲訪問都基于接口調(diào)用。當然如果你的項目根本沒有切換數(shù)據(jù)庫的需求,我更建議去掉這一環(huán)節(jié),直接在基類中實現(xiàn)單例模式,業(yè)務(wù)邏輯層直接調(diào)用。

圖中可以看到接口層獨立于實現(xiàn)部分,我將具體業(yè)務(wù)實體模型和接口 單獨放在了OSS.Core.DomainMos 類庫中,一方面是為了實體模型在各模塊中的共用,另一方面解耦業(yè)務(wù)邏輯層(Services)和倉儲層(Reps)之間的依賴關(guān)系。

同時一個項目中數(shù)據(jù)庫訪問代碼多數(shù)都會以CRUD為主,所以這里我定義了一個基礎(chǔ)接口(IBaseRep),其包含的方法主要有(表達式部分在后邊介紹):

OSS.Core基于Dapper封裝(表達式解析+Emit)倉儲層的構(gòu)思及實現(xiàn)

具體的業(yè)務(wù)數(shù)據(jù)接口繼承至基礎(chǔ)接口就好,其中表達式部分是我自己做了一個封裝,后邊會簡單介紹。

 

  2. 倉儲基類實現(xiàn)(BaseRep)

首先,如圖所示,我們實現(xiàn)了讀寫分離的兩個擴展,其實最終都會經(jīng)過Excute方法,那么這里展示下方法的具體實現(xiàn):

OSS.Core基于Dapper封裝(表達式解析+Emit)倉儲層的構(gòu)思及實現(xiàn)

可以看到在這個方法提供了一個針對IDbConnection的委托,提供調(diào)用層自由使用Dapper方法的同時,統(tǒng)一了數(shù)據(jù)訪問方法入口,便于日志記錄,和排查。

 

其次,在很多項目中會出現(xiàn)用戶和訂單在不同庫中的這類情況,因為涉及到分庫的情況,所以需要子類中能有修改連接串能力,那么這里我通過構(gòu)造函數(shù)的形式,提供了兩個可空參數(shù):

OSS.Core基于Dapper封裝(表達式解析+Emit)倉儲層的構(gòu)思及實現(xiàn)

可以看到,如果子類中定義了自己的連接串,則以子類自定義為主,否則走默認的連接信息。

最后,我們也實現(xiàn)了針對基礎(chǔ)接口方法的具體實現(xiàn),舉一示例:

OSS.Core基于Dapper封裝(表達式解析+Emit)倉儲層的構(gòu)思及實現(xiàn)

同時,為了保證子類中能夠加入緩存處理,所以采用了虛方法(virtual)的形式,保證子類能夠重寫。

 

  3. 基于Connection的擴展

這個地方主要分為兩個部分,a. 表達式的解析,以及參數(shù)化的處理   b. 擴展Connection的Insert,Update...等Dapper沒有擴展的方法:

a. 熟悉Expression表達式的朋友應(yīng)該比較了解,表達式本身是一個樹形接口,根據(jù)不同的類型,可以不斷的解析其子表達式,直到不具備繼續(xù)解析的可能。所以這個就很簡單就是遞歸的不斷迭代,根據(jù)其不同的NodeType可以組裝不同的sql元素,因為代碼較長,可以參見github下的SqlExpressionVisitor.cs類,其中參數(shù)的賦值部分,沒有采用反射,而是使用的反射發(fā)射,代碼詳見SqlParameterEmit.cs

b. 有了表達式的擴展之后,就可以獲取對應(yīng)的sql和參數(shù),通過this擴展Connection方法即可,代碼見ConnoctionExtention.cs

四. 調(diào)用示例

1. 我們定義一個簡單UserInfoMo實體(包含mobile等屬性)

2. 定義接口  IUserInfoRep: IBaseRep

3. 定義實現(xiàn)類  UserInfoRep : BaseRep, IUserInfoRep

在不添加其他代碼的基礎(chǔ)上,我們就可以完成下面的調(diào)用:

OSS.Core基于Dapper封裝(表達式解析+Emit)倉儲層的構(gòu)思及實現(xiàn)

 

文章標題:OSS.Core基于Dapper封裝(表達式解析+Emit)倉儲層的構(gòu)思及實現(xiàn)
當前URL:http://muchs.cn/article16/pisggg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google網(wǎng)站制作、云服務(wù)器、品牌網(wǎng)站設(shè)計、品牌網(wǎng)站建設(shè)、ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)