引言 自從
NET 真正走入開發人員那天起
效率
兩個字就一直成為眾多程序員津津樂道的話題
無論是從開發模式(Cross Language)
系統框架(
NET Framework)
還是各種使用方便的工具(VS
NET)
無一不體現出了它的勝人一籌
同時
在另一方面
NET 是否可以真正勝任企業級應用(Enterprise Application)開發的重任
卻依然爭論不斷
褒貶不一
通常來說
對於一個企業級應用
需要考慮的方面很多
如安全
性能
伸縮性
易用性等
在本文中
作者更願意與大家一起探討
NET 下數據訪問層的相關技術
這可能是在多層架構(n
Tier Architecture)誕生之日起就受到廣泛關注的敏感話題
而對於大部分開發人員來說
這也可能是項目中最讓人沮喪的部分
甚或引起爭議最多的部分
在以下論述中
為統一起見
作者暫時將數據訪問層簡稱為DAL(Data Access Layer)
分析問題 簡單統計分析後
就不難發現
DAL之所以讓人畏懼
並非出於技術本身的問題
甚至恰恰相反
很多開發人員認為這是最沒有技術含量的部分之一(就作者經歷的大小項目來看
該層所占的開發時間一般較短
也是很多開發人員不願意承擔的
苦差
)
只是架構需要或者某些思想作怪(如
為DAL而DAL)才加入了這所謂的第四層(傳統三層架構並沒有提出DAL思想)
DAL的提出
確實對傳統的架構模式提出了巨大挑戰
加入的目的肯定也是希望借其進一步提高生產效率
在這種模式下
理想情況是
大部分開發人員從此擺脫DBA之苦
甚或徹底斷絕與數據庫的直接關系
SQL之痛將離我們而去
整個OO世界從此清靜
不過
理想歸理想
能否成為現實則需通過項目檢驗
接下來
作者試圖分析比較流行且較有代表性的幾種解決方案
看看能否從中得出一些有價值的結論
並為我們今後在設計與實現DAL時提供一些借鑒
ADONET 首先
提到
NET下的DAL
立刻映入眼簾的就是ADO
NET
沒錯
幾乎所有的DAL解決方案(請允許作者使用Solution而非Framework)都必須從它發展而來
沒得選擇
這也是具有
NET特色的實現方式(相比較J
EE)
排除商業因素及CLR本身的需要
ADO
NET真正帶給我們的東西不多
值得一提的也就DataSet(就作者經歷的項目來說
使用更多的是DataTable和DataView)
從微軟早期的內存數據庫(Memory Database)鮮有人問津到今天的DataSet大行其道
這其中的曲折實非片言只語所能道盡
總之
有一點可以肯定
正是有了DataSet這種選擇
NET下的DAL才能象今天這般百花齊放
大家的思路才能更趨開闊
Duwamish 這方面有很多好的Sample
最經典的莫過於微軟大力推薦的企業級開發套餐
Duwamish
對於希望學習
NET下DAL設計的朋友
這是一個不錯的起點
這方面的完整剖析
大家可以參考
CSDN開發高手
本文不再贅述
作者自己參與的一個項目中就使用了Duwamish方案
當時限於工期
感覺這是一個很好的參考
沒做深入分析就開始設計了
現在回想起來
發現還是有很多不足之處
舉個簡單的例子
Duwamish方案中並沒有考慮Cache Management
而這對於企業級應用來說
某些時候就是一個不得不考慮的問題
另一方面
雖然Duwamish中告別了SQL語句(全部采用存儲過程實現)
但數據庫痕跡依舊十分明顯
比如
某些字段名稱的定義
關聯表名稱的定義等等
還有一個十分頭疼的問題是在開發過程中體現出來的
一開始
那些比較簡單的數據表還比較容易實現
到了一些包含相互關系的數據表時
我們的DAL工程師就感到了壓力
到後來
幾乎又做了一遍DBA在數據庫建模時早已做過的工作
只不過
這次將數據庫腳本換作了C# 實現(或者說
將數據庫結構換成了表面上具有OO特色的DataSet)而已
可能
Duwamish的實現比較經典
但在實際應用中
有時並不意味著Best Practice
就拿我們的項目來說
雖然成功交付
但無論從模型復用角度
還是開發效率來說
都不能算很成功
套用一句流行語
其實我們可以做得更好!
PetShop ADO
NET上另一個值得參考的DAL實現就是鼎鼎大名的PetShop
當然了
與Duwamish相似
名氣大未必真的實用
PetShop雖然彌補了Duwamish在某些方面的不足
例如
通過Factory支持多種數據庫存儲
引入了Cache機制
提供了更為便利的SQL Helper
但也同時帶來了另一些問題
其中
最麻煩的就是SQL語句的引入
而且還是針對不同數據庫存儲的不同SQL語句(主要是SQL Server與Oracle的參數表示方式不同)
另一方面
PetShop雖然沒有使用DataSet而代之以更為簡潔的普通實體對象(Model)
但它還是將DataReader的結果轉換到了包含實體對象的列表集合中供離線使用
從這個意義上說
可謂換湯不換藥
甚至
在某些場合
例如
需要進行數據過濾
或者在主從數據間導航
反而更為不便(此時
簡單的Collection或者List是無法滿足需求的
DBA與DAL開發人員只能再提供其它的方法來達到目的)
從上述兩個例子中
我們可以看出
即使在微軟的開發團隊中
也沒有能夠在DAL這個問題上達成一致
這方面的更詳細信息
有興趣的朋友可以參考如下文章
實戰 上面剖析的兩個解決方案
讓我們看到了它們各自的優勢與不足
而企業級應用的復雜環境也不太可能要求一個放之四海而皆准的框架就能解決所有難題
因此
只能根據具體情況具體分析
作者曾經參與一個(
NET)大型外包項目的開發工作
有幸一睹其DAL的設計思想
深感震撼
在此與各位朋友一起共同探討
以SQL Server所帶Northwind數據庫為例
如下就是一段基於該DAL的調用代碼(作者做了一些名稱上的調整)
// 根據EmployeeID返回其Title
boEmp = new EmployeeDAL();
boEmp
Keys[
Emp_ID
] =
; // 注意
實際字段名為
EmployeeID
boEmp
Select();
string strTitle = boEmp[
Emp_Title
]; // 注意
實際字段名為
Title
……
// 根據 City 返回所有符合條件的 Employee
boEmp = new EmployeeDAL();
boEmp
Keys[
Emp_City
] =
Seattle
;
boEmp
Select(); // 注意
該方法與上面的調用完全相同
DataTable dtEmp = boEmp
Table;
如果不考慮對象創建(可以采用Object Pooling或者Cached Object)以及調用後的處理
實際的代碼只有兩行!
更讓人吃驚的是
上述EmployeeDAL類沒有任何真正意義上的實現代碼
僅僅是聲明了類名
然後從一個通用基類繼承而已!!
最優雅的地方還不在於此
實際上
就算在那個基類中
也根本看不到SqlConnection或者OracleAdapter之類的幫派之爭
相信大家也猜出來了
沒錯
它是借鑒了PetShop的實現
采用了Factory模式來保證DAL可以適用於不同的數據庫存儲
不過
這種實現與PetShop還是有很大的區別
至少
它沒有產生不同的SQL語句
更沒有出現不同的參數調用方式(SQL Server中一般使用
@
符號
Oracle中一般使用
符號)
所有幫派一視同仁!
這其中
當然得益於Factory的實現技巧
但更重要的因素還在於設計方式的精妙
其實
在
NET Framework中
已經提供了這種設計方式的基石
說白了
就是System
Data中的那些Interface(如
IDBConnection
IdataAdapter等)
在這樣的設計基礎上
我們針對每一個DAL類
就不再需要為不同的數據庫存儲提供不同的數據存取實現了
例如
在PetShop中
針對訂單數據需要實現Order類
很自然的
系統為SQL Server與Oracle分別實現了Order類並使用不同Provider(SqlClient
OracleClient)提供的方法進行操作
而在實際調用時
PetShop通過Factory模式動態創建真正的Order類並激活相應的方法
一個面向不同數據庫存儲的方案就躍然紙上
其實
PetShop這種方案已經比較靈活了
如果更能省去
撰寫不同Order類
之苦
那就真的送佛送到天了J
而所有這些功能
在作者所參與的這個項目中
已經完全搞定了!
至於上面的
EmployeeDAL(當然
包括其它所有DAL類)沒有任何真正實現代碼
只不過玩了一個小小的配置技巧而已
將不同的DAL類與相關的Stored Procedure(請注意
不是Table或View)按照Namespace分別存儲到XML文件中
可能大家已經看出來了
理論上
甚至只需要一個DAL類就可以完成上述所有的工作!但在實際操作中
不同的DAL類可能還是有一些數據處理上的細微差別(比如
數據校驗
格式轉換等)
總的來說
在這樣一個大項目中
不可能要求所有開發人員(除了DBA
DAL Framework Developer)都去了解ADO
NET的方方面面
雖然作者對此頗有研究
但在這個項目中
卻從頭至尾只用到了兩個類
DataTable
DataView(甚至連Transaction都無需了解)!
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25522.html