在我的開發框架系列中,底層數據庫的配置處理都是差不多的,框架整體支持SQLServer、DB2、MySql、ODP.NET(Oracle)、PostgreSQL、SQLite、SqlEx等數據庫的,往往客戶在使用框架的時候會問,框架支持哪些數據庫、各種數據庫配置信息、如何實現數據庫分庫處理、如何同時支持SQLServer和Oracle等數據庫支持、如何實現數據庫連接字符串加密等問題,本篇隨筆逐一進行介紹。
1、框架支持的數據庫介紹
框架底層數據庫訪問采用了微軟企業庫實現,因此在處理多種數據庫訪問的時候,能夠提供統一的訪問處理操作,同時對不同的數據庫支持操作也是非常不錯的。下圖是框架底層數據庫的支持情況。
采用了微軟企業庫Enterprise Library作為我們底層的數據庫訪問模塊后,對於多種數據庫的訪問操作,就會統一采用這個企業庫的數據庫訪問對象,操作起來非常一致,為了對不同數據庫的常規增刪改查等一些操作進行進一步的封裝,以達到簡化代碼的目的,因此我們可以為每個不同的數據庫定義一個數據訪問操作基類,以便實現一些不同數據庫差異性的處理,但是它們還是有一個共同的數據訪問基類。
采用不同的數據庫,我們需要為不同數據庫的訪問層進行生成處理,如為SQLServer數據的表生成相關的數據訪問層DALSQL,里面放置各個表對象的內容,不過由於采用了相關的繼承類處理和基於數據庫的代碼生成,需要調整的代碼很少。
這樣整合多種數據庫支持的底層后,整個數據訪問的架構設計如下所示。
2、各種數據庫配置信息
對於默認支持的SQLServer數據庫,它的連接字符串如下所示。
<?xml version="1.0"?> <configuration> <configSections> <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data"/> </configSections> <connectionStrings> <!--SQLServer數據庫的連接字符串--> <add name="sqlserver" providerName="System.Data.SqlClient" connectionString="Persist Security Info=False;Data Source=(local);Initial Catalog=WinFramework;Integrated Security=SSPI"/> </connectionStrings> <dataConfiguration defaultDatabase="sqlserver"> </dataConfiguration> </configuration>
上面的sqlserver數據庫連接信息是采用信任模式配置的,如果我們基於局域網,那么需要配置對應的IP或者sa用戶名和密碼的方式,配置信息如下所示。
<add name="sqlserver2" providerName="System.Data.SqlClient" connectionString="Data Source=192.168.1.10;Initial Catalog=CRM;Persist Security Info=True;User ID=sa;Password=123456"/>
不過對於一些擴展支持的數據庫,我們還需要添加一些映射處理,如對於MySQL的支持,我們需要添加連接字符串:
<!--MySQL數據庫的連接字符串--> <add name="mysql" providerName="MySql.Data.MySqlClient" connectionString="Server=localhost;Database=WinFramework;Uid=root;Pwd=123456;"/>
還需要添加ProviderMappings的支持,如下所示的XML。
<dataConfiguration defaultDatabase="mysql"> <providerMappings> <add databaseType="EntLibContrib.Data.MySql.MySqlDatabase, EntLibContrib.Data.MySql" name="MySql.Data.MySqlClient" /> </providerMappings> </dataConfiguration>
下面我列出所有不同數據庫的連接字符串以及映射關系的一個完整版本,供參考。
<?xml version="1.0"?> <configuration> <configSections> <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data"/> </configSections> <connectionStrings> <!--Sqlserver數據庫的連接字符串--> <add name="sqlserver" providerName="System.Data.SqlClient" connectionString="Persist Security Info=False;Data Source=(local);Initial Catalog=WinFramework;Integrated Security=SSPI"/> <!--PostgreSQL數據庫的連接字符串--> <add name="npgsql" providerName="Npgsql" connectionString="Server=localhost;Port=5432;Database=postgres;User Id=postgres;Password=123456"/> <!--MySQL數據庫的連接字符串--> <add name="mysql" providerName="MySql.Data.MySqlClient" connectionString="Server=localhost;Database=WinFramework;Uid=root;Pwd=root;"/> <!--路徑符號|DataDirectory|代表當前運行目錄--> <add name="access" providerName="System.Data.OleDb" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\WinFramework.mdb;User ID=Admin;Jet OLEDB:Database Password=;" /> <!--sqlite數據庫字符串,路徑符號|DataDirectory|代表當前運行目錄--> <add name="sqlite" providerName="System.Data.SQLite" connectionString="Data Source=|DataDirectory|\WinFramework.db;Version=3;" /> <!--Oracle數據庫的連接字符串--> <add name="oracle" providerName="System.Data.OracleClient" connectionString="Data Source=orcl;User ID=win;Password=win"/> <!--達夢數據庫的連接字符串--> <add name="Dm" providerName="Dm" connectionString="Server=localhost;User ID=SYSDBA;PWD=SYSDBA;Database=WINFRAMEWORK;" /> <!--IBM DB2數據庫的連接字符串--> <add name="db2" providerName="IBM.Data.DB2" connectionString="database=whc;uid=whc;pwd=123456"/> <!--采用OdpNet方式的Oracle數據庫的連接字符串--> <add name="oracle2" providerName="Oracle.DataAccess.Client" connectionString="Data Source=orcl;User id=win;Password=win;" /> </connectionStrings> <dataConfiguration defaultDatabase="sqlserver"> <providerMappings> <add databaseType="EntLibContrib.Data.PostgreSql.NpgsqlDatabase, EntLibContrib.Data.PostgreSql" name="Npgsql" /> <add databaseType="EntLibContrib.Data.MySql.MySqlDatabase, EntLibContrib.Data.MySql" name="MySql.Data.MySqlClient" /> <add databaseType="EntLibContrib.Data.SQLite.SQLiteDatabase, EntLibContrib.Data.SqLite" name="System.Data.SQLite" /> <add databaseType="EntLibContrib.Data.Dm.DmDatabase, EntLibContrib.Data.Dm" name="Dm" /> <add databaseType="EntLibContrib.Data.DB2.DB2Database, EntLibContrib.Data.DB2" name="IBM.Data.DB2" /> <add databaseType="EntLibContrib.Data.OdpNet.OracleDatabase, EntLibContrib.Data.OdpNet" name="Oracle.DataAccess.Client" /> </providerMappings> </dataConfiguration> <appSettings> <!--組件的數據庫類型:access、sqlserver、sqlite、oracle等,默認為sqlserver可不寫--> <add key="ComponentDbType" value="sqlserver"/> </appSettings> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> <supportedRuntime version="v2.0.50727"/> </startup> </configuration>
里面包括了支持的各種數據庫的連接字符串的寫法。
3、如何實現數據庫分庫處理、如何同時支持SQLServer和Oracle等數據庫支持
由於整個框架的設計抽象了多種數據庫的處理模型,因此數據庫分庫處理實現也是比較方便的,數據庫的分庫處理和同時支持SQLServer和Oracle等數據庫的操作是類似的,他們都是對多個數據庫(包括不同各類型)進行訪問處理。
之前我在隨筆《Winform開發框架中實現多種數據庫類型切換以及分拆數據庫的支持》這里也介紹了具體的實現處理,其實我們使用的同時支持多數據庫的操作代碼是比較簡單的,我們可以在代碼里面通過調用BLL層類的接口SetConfitName來指定特定的數據庫,如下代碼所示。
//指定業務類的數據庫配置 BLLFactory<Asset>.Instance.SetConfigName("workflow"); BLLFactory<StoreAddress>.Instance.SetConfigName("workflow");
有時候,可能BLL對象有可能出現相同的情況,但是需要訪問不同庫里面的表對象,那么我們可以在使用后恢復默認的配置信息。
BLLFactory<DictData>.Instance.SetConfigName("workflow");//使用業務庫 Dictionary<string, string> dict = BLLFactory<DictData>.Instance.GetDictByDictType(dictTypeName); BLLFactory<DictData>.Instance.SetConfigName(null);//恢復默認
以上代碼就是先訪問workflow配置的數據庫信息,獲取字典信息后恢復默認的數據庫信息。
上面那種方式是對於同種類型數據庫的接口切換,如果不同的數據庫類型,如一個是SQLServer,一個是Oracle,那么就可以多指定一個參數即可,如下代碼所示。
//指定使用oracle類型的數據庫配置 BLLFactory<DictData>.Instance.SetConfigName("workflow", "oracle");//使用業務庫 Dictionary<string, string> dict = BLLFactory<DictData>.Instance.GetDictByDictType(dictTypeName); BLLFactory<DictData>.Instance.SetConfigName(null);//恢復默認
雖然我們一般使用一個庫,但是如果是分庫,或者要同時支持多個數據庫類型,基本上處理還是很方便的。
如果對於通用類型的數據庫處理,我們可以使用公用類庫里面的CommonDAL類進行處理。這個類庫可以很方便的處理視圖、存儲過程、或者常規的接口查詢操作,不需要和具體的實體類綁定的接口。
它的定義如下所示。
4、數據庫字符串加密處理
很多情況下,我們為了部署應用,需要公開數據庫連接字符串信息,但是我們又不想讓使用者很容易的獲取到我們的連接字符串里面的用戶名和密碼敏感信息,這時候連接字符串加密就是比較必要的了。
處理方式就是我們創建一個工具,使用自己知道的加解密規則來處理連接字符串的加解密處理。
處理的過程大概如下所示。
1)找到app.config文件,打開內容編輯。
2)找到數據庫(如SQLServer)連接字符串的connectionString字符串,如下所示。
<add name="sqlserver" providerName="System.Data.SqlClient" connectionString="Persist Security Info=False;Data Source=(local);Initial Catalog=CRM;Integrated Security=SSPI"/>
3)提取里面的connectionString字符串部分,放到上面的加密軟件里面進行加密,然后把加密內容替換connectionString字符串,變為如下所示的配置信息。
<add name="sqlserver" providerName="System.Data.SqlClient" connectionString="9Fs/vPhm24CYa0mXCLAMYOJmbBHq/qQAjdbVdbeOhS5L0d8WGhHUR3iIyFZydEV8cPmlPHfDTnwJZMr9xkMAxuNtPKUsIdKTjlWInpf+Vc+UD2gtYIE3FnvL06KcHzX+"/>
4)保存文件,配置加密字符串完成。
這個配置信息在框架的處理的時候有對應的解密處理規則,可以正常解析加密字符串即可。
如果要了解或者修改其中的對應解密處理操作,可以定位擴展公用類庫里面數據庫訪問層,如下所示。
定位到對應的數據庫訪問類,然后找到下面的對應函數了解即可。