新聞中心
關(guān)于?DAO?數(shù)據(jù)訪問對象設(shè)計(jì)其實(shí)是關(guān)于?GOFrame?框架工程化實(shí)踐中比較重要一塊設(shè)計(jì)。

創(chuàng)新互聯(lián)是專業(yè)的牙克石網(wǎng)站建設(shè)公司,牙克石接單;提供成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站,網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行牙克石網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!
?DAO?設(shè)計(jì)結(jié)合?GoFrame?的?ORM?組件性能和易用性都很強(qiáng),可以極大提高開發(fā)和維護(hù)效率??赐瓯菊鹿?jié)內(nèi)容之后,小伙伴們應(yīng)該能夠理解并體會到使用?DAO?數(shù)據(jù)庫訪問對象設(shè)計(jì)的優(yōu)點(diǎn)。
一、現(xiàn)有ORM使用示例
1、需要定義模型
用戶基礎(chǔ)表(僅作演示,真實(shí)的表有數(shù)十個(gè)字段)
醫(yī)生信息表(僅作演示,真實(shí)的表有上百個(gè)字段)
2、GRPC接口實(shí)現(xiàn)示例
一個(gè)簡單的?GRPC?查詢信息接口。
一個(gè)簡單的?GRPC?數(shù)據(jù)查詢接口
二、現(xiàn)有痛點(diǎn)描述
1、必須要定義tag關(guān)聯(lián)表結(jié)構(gòu)與struct屬性,無法做到自動映射
表字段與實(shí)體對象屬性名稱之間原本就有一定的關(guān)聯(lián)規(guī)則,沒有必要定義和維護(hù)大量的?tag?定義。
大量非必要的?tag?定義,用于指定數(shù)據(jù)表字段到實(shí)體對象屬性映射
2、不支持通過返回對象指定需要查詢的字段
無法通過返回的對象數(shù)據(jù)結(jié)構(gòu)指定查詢字段,要么只能?SELECT *? ,要么只能通過額外的方法手動錄入查詢字段,效率很低下。
常見的SELECT *操作,無法根據(jù)接口對象指定查詢字段
3、無法對輸入對象屬性名稱進(jìn)行自動字段過濾
定義了輸入與輸出數(shù)據(jù)結(jié)構(gòu),輸出的數(shù)據(jù)結(jié)構(gòu)已經(jīng)包含我們需要查詢的字段名稱。開發(fā)者輸入定義的返回對象,期望在查詢的時(shí)候僅查詢我需要的字段名稱,多余的屬性則不會執(zhí)行查詢,自動過濾掉。
4、需要創(chuàng)建中間查詢結(jié)果對象執(zhí)行賦值轉(zhuǎn)換
查詢結(jié)果不支持?struct?智能轉(zhuǎn)換,需要額外定義一個(gè)中間?model?模型,再通過其他工具進(jìn)行復(fù)制,效率低。
存在中間臨時(shí)的模型對象,用于承接查詢結(jié)果及返回結(jié)構(gòu)對象賦值轉(zhuǎn)換
5、需要提前初始化返回對象,不管有無查詢到數(shù)據(jù)
這種方式不僅不優(yōu)雅,對性能也有影響,還對?GC?不太友好。期望查詢到數(shù)據(jù)時(shí)再自動創(chuàng)建返回對象,沒有查詢到數(shù)據(jù)時(shí)什么都不要做。
需要預(yù)先初始化返回對象,不管有無查詢到數(shù)據(jù)
6、通篇使用底層裸DB對象操作,沒有DAO對象封裝操作
大部分的Golang初學(xué)者似乎都傾向于使用一個(gè)全局的?DB?對象,在查詢的時(shí)候通過?DB?對象生成特定表的?Model?對象再執(zhí)行?CURD?操作,這是一種面向過程的使用方式。這種方式并沒有代碼分層的設(shè)計(jì)可言,使得數(shù)據(jù)操作和業(yè)務(wù)邏輯高度耦合。
原始數(shù)據(jù)庫對象操作方式,沒有?DAO?封裝
7、隨處可見的字符串硬編碼,如表名和字段的硬編碼
舉個(gè)例子,?userId?這個(gè)字段假如一不小心寫成了?UserId?或者?userid?,測試的時(shí)候如果沒有完全覆蓋到,在一定的條件下才觸發(fā)查詢操作,是不是會造成新的一場事故呢?
大量的字符串硬編碼
8、底層ORM引起太多的指針屬性定義
指針屬性對象為業(yè)務(wù)邏輯處理埋下隱患,開發(fā)者在代碼邏輯中需要在指針與屬性之間來回切換,特別是一些基礎(chǔ)類型往往需要通過重新取值的方式傳遞參數(shù)。如果輸入?yún)?shù)是?interface{}?類型,那么更容易引起?BUG?
?BUG?示例,指針屬性使用不當(dāng),引起地址比較邏輯錯誤。
同時(shí)也影響了業(yè)務(wù)模型結(jié)構(gòu)體定義設(shè)計(jì),對開發(fā)者造成了錯誤習(xí)慣引導(dǎo)(上層業(yè)務(wù)模型的指針屬性往往是為了迎合底層數(shù)據(jù)表實(shí)體對象,方便數(shù)據(jù)傳遞)。
值得注意一個(gè)常見錯誤,就是將底層數(shù)據(jù)實(shí)體模型當(dāng)做頂層業(yè)務(wù)模型使用。特別是在底層數(shù)據(jù)實(shí)體對象使用指針屬性的場景下,該問題十分明顯。
9、可觀測性的支持:Tracing、Metrics、Logging
數(shù)據(jù)庫?ORM?作為業(yè)務(wù)項(xiàng)目最關(guān)鍵核心的組件,可觀測性的支持至關(guān)重要。但是大多數(shù)被認(rèn)為奉承所謂做得越少越"專業(yè)"的?ORM?組件卻不曾深諳此道。
10、數(shù)據(jù)集合與代碼數(shù)據(jù)實(shí)體結(jié)構(gòu)不一致
當(dāng)通過人工維護(hù)數(shù)據(jù)實(shí)體結(jié)構(gòu)時(shí),數(shù)據(jù)集合與代碼數(shù)據(jù)實(shí)體結(jié)構(gòu)往往會出現(xiàn)不一致的風(fēng)險(xiǎn),開發(fā)和維護(hù)成本高。
三、改進(jìn)方案設(shè)計(jì)
1、查詢結(jié)果對象無需特殊標(biāo)簽定義,全自動關(guān)聯(lián)映射
2、支持根據(jù)指定對象自動識別查詢字段,而不是全部?SELECT * ?
3、支持根據(jù)指定對象自動過濾不存在的字段內(nèi)容
4、使用?DAO?對象封裝代碼設(shè)計(jì),通過對象方式操作數(shù)據(jù)表
5、?DAO?對象將關(guān)聯(lián)的表名及字段名進(jìn)行封裝,避免字符串硬編碼
6、無需提前定義實(shí)體對象接受返回結(jié)果,無需創(chuàng)建中間實(shí)體對象用于接口返回對象的賦值轉(zhuǎn)換
7、查詢結(jié)果對象無需提前初始化,查詢到數(shù)據(jù)時(shí)才會自動創(chuàng)建
8、內(nèi)置支持?OpenTelemetry?標(biāo)準(zhǔn),實(shí)現(xiàn)可觀測性,極大提高維護(hù)效率、降低成本
9、支持?SQL?日志輸出能力,支持開關(guān)功能
10、數(shù)據(jù)模型、數(shù)據(jù)操作、業(yè)務(wù)邏輯解耦,支持?Dao?及?Model?代碼工具化自動生成,保證數(shù)據(jù)集合與代碼數(shù)據(jù)結(jié)構(gòu)一致,提高開發(fā)效率,便于規(guī)范落地
11、等等。
采用?DAO?設(shè)計(jì)改進(jìn)后的代碼示例
網(wǎng)站題目:創(chuàng)新互聯(lián)GoFrame教程:GoFrameDAO對象封裝設(shè)計(jì)-痛點(diǎn)及改進(jìn)
文章鏈接:http://m.fisionsoft.com.cn/article/djohcpj.html


咨詢
建站咨詢
