Winform開發框架中實現多種資料庫型別切換以及分拆資料庫的支援
在很多應用系統裡面,雖然一般採用一種資料庫執行,但是由於各種情況的需要,可能業務系統會部署在不同型別的資料庫上,如果開發的系統能夠很方便支援多種資料庫的切換,那可以為我們減少很多煩惱,同時提高系統的適應性和強壯型。還有一種情況,由於業務資料庫的不斷膨脹或者方便資料庫的切割隔離,有時候也會把不同的業務資料庫進行分拆,如許可權提供資料庫,客戶關係管理資料庫,工作流程資料庫,企業營運資料庫等等,因此在一個系統裡面,同時使用2個或者以上的資料庫的情況也是有的。針對這兩種情況,本文介紹在我的Winform開發框架(也使用我的其他框架),如何具體處理這兩個問題的。
在我的各種開發框架裡面,底層都是採用同一種資料庫的訪問方式,就是採用了Enterprise Library的資料庫訪問模組,這個是微軟開源的企業應用模組,裡面各種應用模組,都堪稱是開發的最佳實踐。當然利用裡面的資料庫訪問模組,是很廣泛的,這個資料庫訪問模組,可以通過配置的方式支援多種資料庫的變化。因此整合到我的Winform開發框架裡面,也很容易實現這種多資料庫的方式處理。
Winform開發框架,常見的分層模式,可以分為UI層、BLL層、DAL層、IDAL層、Entity層、公用類庫層等等,B/S的Web開發框架也是提供類似的架構模式,它們只是Web介面層有所不同,這樣就給我們提供了一個統一性的開發模式,使得開發起來更加高效,統一性更好。框架介面層以下的架構設計圖如下所示。
1、支援多資料庫的設定
1)資料庫訪問基類的瞭解
為了介紹支援多種資料庫的模式,我們需要先來了解下整個框架的層次結構。
AbstractBaseDAL是抽象了所有資料庫實現的超級基類。
BaseDALSQL是針對SqlServer資料庫部分調整基類(很小的調整)。
BaseDALSQLite是針對Sqlite資料庫的部分調整基類(很小的調整)。
BaseDALMySql是針對MySqlite資料庫的部分調整基類(很小的調整)。
BaseDALAccess是針對Access資料庫的部分調整基類(很小的調整)。
IBaseDAL是所有基礎資料庫訪問類的介面。
資料訪問介面實現層(如Customer)和介面定義層(ICustomer)一樣,都有一個基類,如基於SqlServer實現的基類為BaseDALSQL,這個基於SqlServer的資料訪問基類,它也是繼承自一個超級基類(大多數的實現在這裡)AbstractBaseDAL。他們之間的繼承關係如下所示
而我們剛才在專案工程的圖裡面看到,BaseDALSQL、IBaseDAL、AbstractBaseDAL這些類庫由於具有很大的通用性,為了減少在不同的專案中進行復制導致維護問題,因此我們全部把這些經常使用到的基類或者介面,抽取到一個獨立的類庫裡面,為了和普通的DotNET公用類庫命名進行區分(WHC.Framework.Commons),我們把它命名為WHC.Framework.ControlUtil。
2)多資料庫的程式碼實現
為了實現多資料庫的支援,我們需要在配置檔案裡面讀取相關的配置,看具體是構造那種該資料庫的,然後進行初始化不同的程式集類,從而實現呼叫不同資料庫型別的資料庫訪問類。
在BaseBLL的Init函式裡面的實現程式碼如下所示。
#region 根據不同的資料庫型別,構造相應的DAL層 AppConfig config = new AppConfig(); string dbType = config.AppConfigGet("ComponentDbType"); if (string.IsNullOrEmpty(dbType)) { dbType = "sqlserver"; } dbType = dbType.ToLower(); string DALPrefix = ""; if (dbType == "sqlserver") { DALPrefix = "DALSQL."; } else if (dbType == "access") { DALPrefix = "DALAccess."; } else if (dbType == "oracle") { DALPrefix = "DALOracle."; } else if (dbType == "sqlite") { DALPrefix = "DALSQLite."; } else if (dbType == "mysql") { DALPrefix = "DALMySql."; } #endregion this.dalName = bllFullName.Replace(bllPrefix, DALPrefix);//替換中級的BLL.為DAL.,就是DAL類的全名 baseDal = Reflect<IBaseDAL<T>>.Create(this.dalName, dalAssemblyName);//構造對應的DAL資料訪問層的物件類
在具體的業務物件的呼叫的時候,我們不知道它具體是呼叫哪個資料庫的處理類進行處理的,只需要呼叫它的基礎介面就可以了,如下是介面層的部分呼叫程式碼。
//刪除關聯的附件 if (!string.IsNullOrEmpty(ids)) { string[] idArray = ids.Split(','); foreach (string id in idArray) { InformationInfo info = BLLFactory<Information>.FindByID(id); if (info != null && !string.IsNullOrEmpty(info.Attachment_GUID)) { BLLFactory<FileUpload>.Instance.DeleteByAttachGUID(info.Attachment_GUID); } } }
在具體的配置檔案裡面,我們就可以根據需要配置好相關的資料庫了。
根據Enterprise Library的配置,我們只要制定了<dataConfiguration defaultDatabase="sqlserver">,那麼就會獲取sqlServer的節點,而程式碼通過解析ComponentDbType配置項,就可以構造對應的資料庫訪問物件了。兩者合一就可以正確獲取到處理物件,併成功處理資料庫的訪問。
<configuration> <configSections> <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data"/> </configSections> <connectionStrings> <add name="sqlserver" providerName="System.Data.SqlClient" connectionString="Persist Security Info=False;Data Source=(local);Initial Catalog=MVCWebMis;Integrated Security=SSPI"/> <add name="access" providerName="System.Data.OleDb" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\ComponentData.mdb;User ID=Admin;Jet OLEDB:Database Password=;"/> <add name="sqlite" providerName="System.Data.SQLite" connectionString="Data Source=|DataDirectory|\ComponentData.db;Version=3;"/> <add name="oracle" providerName="System.Data.OracleClient" connectionString="Data Source=whcdb;User ID=whc;Password=whc"/> </connectionStrings> <dataConfiguration defaultDatabase="sqlserver"> <providerMappings> <add databaseType="EntLibContrib.Data.SQLite.SQLiteDatabase, EntLibContrib.Data.SqLite" name="System.Data.SQLite"/> </providerMappings> </dataConfiguration> <appSettings> <!--元件的資料庫型別:access、sqlserver、sqlite等--> <add key="ComponentDbType" value="sqlserver"/>
2、支援分拆不同資料庫的設定
上面介紹的方式,一次性只能訪問一個資料庫,因此預設在程式碼構造資料庫訪問物件的時候,是通過下面的程式碼進行的。
Database db = DatabaseFactory.CreateDatabase();
這樣每次只會獲取defaultDatabase設定的資料庫進行構造,如果我們在一個系統裡面,同時支援多個資料庫的訪問,那麼我們應該如何處理呢。
在框架的基類AbstractBaseDAL裡面,我們對構造資料庫的程式碼進行了封裝。
/// <summary> /// 根據配置資料庫配置名稱生成Database物件 /// </summary> /// <returns></returns> protected virtual Database CreateDatabase() { Database db = null; if (string.IsNullOrEmpty(dbConfigName)) { db = DatabaseFactory.CreateDatabase(); } else { db = DatabaseFactory.CreateDatabase(dbConfigName); } return db; }
而每個DAL層都會繼承自AbstractBaseDAL,這樣也就可以通過在DAL層指定dbConfigName進行使用不同的資料庫的了。
但是這樣問題出現了,假如我們有5個不同型別(SqlServer、Oracle、Mysql、Access、Sqlite)的資料庫的DAL層,那麼每個DAL層的實現類都要寫一些程式碼,這樣挺不方便,那麼是否可以把它抽象到BLL層,這樣只寫一次配置就可以了,這個思路很好,我們具體來看看如何實現。
1)在IBaseDAL層定義介面
/// <summary> /// 資料訪問層的介面 /// </summary> public interface IBaseDAL<T> where T : BaseEntity { /// <summary> /// 設定資料庫配置項名稱 /// </summary> /// <param name="dbConfigName">資料庫配置項名稱</param> void SetDbConfigName(string dbConfigName);
............. }
2、在AbstractBaseDAL新增預設實現程式碼
/// <summary> /// 資料訪問層的超級基類,所有資料庫的資料訪問基類都繼承自這個超級基類,包括Oracle、SqlServer、Sqlite、MySql、Access等 /// </summary> public abstract class AbstractBaseDAL<T> where T : BaseEntity, new() { /// <summary> /// 設定資料庫配置項名稱 /// </summary> /// <param name="dbConfigName">資料庫配置項名稱</param> public virtual void SetDbConfigName(string dbConfigName) { this.dbConfigName = dbConfigName; }
.................... }
3、在BaseBLL裡面的Init函式進行呼叫設定處理
/// <summary> /// 引數賦值後,初始化相關物件 /// </summary> /// <param name="bllFullName">BLL業務類的全名(子類必須實現),子類建構函式傳入this.GetType().FullName</param> /// <param name="dalAssemblyName">資料訪問層程式集的清單檔案的檔名,不包括其副檔名。設定為NULL或預設為Assembly.GetExecutingAssembly().GetName().Name</param> /// <param name="bllPrefix">BLL名稱空間的字首(BLL.)</param> /// <param name="dbConfigName">資料庫配置項名稱</param> protected void Init(string bllFullName, string dalAssemblyName = null, string bllPrefix = "BLL.") { ............. baseDal.SetDbConfigName(dbConfigName); //設定資料庫配置項名稱 }
4、在具體BLL層的業務類進行初始化處理。
/// <summary> /// 政策法規公告動態 /// </summary> public class Information : BaseBLL<InformationInfo> { public Information() : base() { base.Init(this.GetType().FullName, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name, "BLL.", "annotherConfig" ); }
這樣設定後,我們具體呼叫的程式碼不變,但是指定業務的資料庫訪問已經使用了特定的配置項名稱了,如果配置項不存在,那麼還是會獲取預設的配置項進行處理了。
通過這樣的實現步驟,我們就能實現在一個業務系統裡面,分拆不同的資料庫,進行統一管理,而且又不會增加額外的呼叫難度,對於我們很多業務表,這種框架的處理方式 ,應該是不錯的。
本文轉自部落格園伍華聰的部落格,原文連結:Winform開發框架中實現多種資料庫型別切換以及分拆資料庫的支援,如需轉載請自行聯絡原博主。
相關文章
- 支援多種資料庫型別的遷移工具資料庫型別
- sqlite 資料庫 支援的資料型別 以及常用的函式SQLite資料庫資料型別函式
- 策略模式實現支援多種類資料庫的DBHelp模式資料庫
- 資料庫中欄位資料型別以及約束資料庫資料型別
- 讓Django支援多種資料庫Django資料庫
- 生產資料庫、開發資料庫、測試資料庫中的資料的區分資料庫
- 資料庫型別區分資料庫型別
- 資料庫訪問抽象類實現專案資料庫靈活切換資料庫抽象
- 多種資料庫型別管理軟體:DBeaverUltimate中文資料庫型別
- goldengate 支援ddl的資料庫型別Go資料庫型別
- 資料庫索引型別及實現方式資料庫索引型別
- Redis多種資料型別以及使用場景Redis資料型別
- DB2 資料庫中的資料型別DB2資料庫資料型別
- SQL Server資料庫中的資料型別隱式轉換問題SQLServer資料庫資料型別
- Django切換MySQL資料庫DjangoMySql資料庫
- .NET 百萬級 大資料插入、更新 ,支援多種資料庫大資料資料庫
- BlueHost主機支援哪些資料庫型別?資料庫型別
- 檢視主資料庫的物件中是否使用了不支援的資料型別資料庫物件資料型別
- 分享一個純 Go 編寫的內嵌型 KV 資料庫 NutsDB,支援事務以及多種資料結構Go資料庫資料結構
- DB2資料庫中的各資料型別DB2資料庫資料型別
- 分散式資料庫拆表拆庫的常用策略分散式資料庫
- Spring-Boot 多資料來源配置+動態資料來源切換+多資料來源事物配置實現主從資料庫儲存分離Springboot資料庫
- 一種專家資料庫的開發與實現 (轉)資料庫
- 資料庫使用者登入、切換以及解鎖資料庫
- oracle資料庫服務切換Oracle資料庫
- MHA實現mysql主從資料庫手動切換的方法MySql資料庫
- 常用資料庫基本資料型別資料庫資料型別
- Hive中的資料型別以及案例實操Hive資料型別
- 如何在MySQL資料庫中使用use來切換資料庫?MySql資料庫
- 基於代理的資料庫分庫分表框架 Mycat實踐資料庫框架
- Redis多機資料庫實現Redis資料庫
- mysql資料庫中decimal資料型別比較大小MySql資料庫Decimal資料型別
- Oracle資料庫中的多種SCN彙總Oracle資料庫
- 資料庫Delete的多種用法資料庫delete
- 使用NineData實現企業級資料庫備份, 資料備份告別“拆盲盒” ?資料庫
- 【資料庫】資料庫儲存元素型別基礎資料庫型別
- 關係型資料庫和非關係型資料庫的區別資料庫
- 資料庫管理丨10種不同的雲開發資料庫管理技巧資料庫