我在前面幾篇介紹過我的Winform開發框架的相關內容,其中主要集中在界面展現以及各層的總體設計上,還沒有空來得及深入進行各個重要細節的講解,今天我們來介紹、討論下我的Winform開發框架之數據訪問層的設計方面的知識,希望對大家有所幫助。
前面介紹過,該Winform開發框架支持多種數據庫的訪問,只需要對配置進行修改即可切換,如下圖所示。
其中我們可以看到,里面有幾種數據訪問層的相關數據,大致知道是通過同一的IDAL數據訪問層接口派生出幾個對應不同數據庫的操作層,由業務邏輯層BLL進行相應的調用,但是具體細節從上圖並不能了解到。
其實他們的大致關系如下圖所示。
首先BLL層,通過BLLFactory對象,根據配置信息,實例化不同的業務訪問對象,轉換為數據訪問層接口進行調用的,BLLFactory通過反射間接方式,構建出不同數據庫對象的數據訪問層,而數據訪問對象,他們都集成了基類BaseDAL,這個基類封裝類了絕大多數的增刪改查等基礎性操作,並通過高度抽象,只需要繼承該基類的子類重載部分函數即可完成較為豐富的操作實現。具體的繼承關系如下圖所示。
由於每個不同數據庫都需要擁有一個BaseDAL,那么很多相同的操作代碼就會發生冗余,因為大多數數據庫的基礎操作是一樣的,只有一部分比較特別,需要進行個性化處理,因此對以上的數據訪問層進行優化設計,得到下面的設計圖,如下所示。
由於把BaseDAL層的通用操作,進一步提升抽象到AbstractBaseDAL 類里面進行管理,因此,BaseDAL雖然在各種數據庫的數據訪問層中存在,但是,卻只是需要實現很少的代碼,如下所示。
因為不同的數據庫,FindFirst(查找第一條)、FindLast(查找最后一條)、Insert2(插入記錄后,返回新增的主鍵值)、以及分頁查詢FindToDataTable、FindWithPager等不同。因此數據訪問層的BaseDAL子類需要覆蓋基類AbstractBaseDAL的這些實現。
通過實現部分個性化數據庫操作的函數及強大的基類
AbstractBaseDAL實現,我們可以看到,整個數據訪問層基類得到非常強大的操作功能,如下所示。
為了說明問題,我列舉幾個上面函數不同的實現給讀者,以便說明問題。
1)SqlServer的FindFirst語句如下:
2)Oracle的FindFirst語句如下:
string sql = string.Format(@"Select * from (Select {0} From {1} Order by {2} ASC) WHERE ROWNUM <= 1 ORDER BY ROWNUM ASC", selectedFields, tableName, GetSafeFileName(sortField));
3)Sqlite的FindFirst語句如下:
string sql = string.Format("Select {0} From {1} Order by {2} ASC LIMIT 1", selectedFields, tableName, GetSafeFileName(sortField));
為了實現功能強大的數據訪問基類,並盡可能減少重復代碼,高度提煉基類是很有效的方法。適當的集成關系,使得代碼量更少,擴展更加容易,這個就是我的Winform框架的優化思想。