上一篇如何打造自己的資料訪問層二中,我們已具體實現了資料訪問層對應的功能,該進行收尾工作了,先來看段代碼,試試上一篇實現的功能:
- string sqlText = "SELECT ID, NAME, VAL FROM TEST";
- string columns = "ID, NAME, VAL";
- DataSet ds = new DataSet();
- DataExecutor execObj = new MSSqlExecutor();
- DataMapping map = new DataMapping();
- map.ExecuteObject = execObj;
- map.TableName = "TEST";
- map.KeyColumns = "ID";
- map.Columns = "ID, NAME, VAL";
- DataMapping map = new DataMapping(execObj.GetInstant(), "TEST", "ID", columns);
- map.Fill(sqlText, "TEST");
- map.SetCommands(DataCommandType.Insert | DataCommandType.Update | DataCommandType.Delete, ds);
- //DataTable方式進行增、刪、改
- bool isSuccess = execObj.Update();
果然已經完成了對資料庫的讀寫操作了,至少不用再寫大段的參數傳遞代碼,功能都已經實現了,是不是就完成了?
仔細看看上面的代碼,實際上還有問題尚未解決,看看這句:
- DataExecutor execObj = new MSSqlExecutor();
竟然在代碼裡直接執行個體化一個MSSql的執行對象,這樣一開始提出的資料庫之間的切換問題根本就沒有從本質上解決。
再回過頭來看上一篇,有一個方法public IDbConnection GetConn(),用來擷取資料連線對像,之前並沒有說明其如何?。
我們知道DBConnection有兩個關鍵資訊:
1、與哪種類型的資料庫產生串連,這個前面已經解決了。
2、傳遞與資料庫連接的帳號資訊、訪問庫資訊的ConnectionString,這個並沒有提及。
看看第二點以前是怎麼做的:
- public IDbConnection GetConn()
- {
- if (conn != null)
- {
- return conn;
- }
- conn = new SqlConnection();
- conn.ConnectionString = 串連字串;
- return conn;
- }
上面出現了串連字串,這個字串從哪來?
總結下,要完成最終的資料訪問輸出,還需要解決兩個問題:
1、動態進行不同資料庫之間的切換。
2、解決資料連線字串的來源問題。
接著就來解決這兩問題,先解決第二個問題,有個比較簡單的方法,將串連字串寫入設定檔中去,資料訪問層只需知道它傳遞過來KEY值:
- <appSettings>
- <add key="ConnStr" value="server=.;uid=sa;password=123456;database=DATA_BASE;max pool size=300"/>
- </appSettings>
第一個問題解決了,只剩下最後一個問題了,如何動態切換不同的資料庫,也就是說,在使用的時候不需要自己NEW一個對象,而是通過第三方來建立一個對象,實際上,設計模式裡已提出了方案,建立型模式,有興趣的朋友可以自行研究,我們這裡只需要用到簡單原廠模式:
- public sealed class ExecutorFactory
- {
- public static DataExecutor Create()
- {
- return Create(DatabaseType.MSSql);
- }
- public static DataExecutor Create(DatabaseType dbType)
- {
- AbstractDataBase dataBase = null;
- Switch(dbType)
- {
- case DatabaseType.MSSql:
- dataBase = new MSSqlDataBase();
- break;
- case DatabaseType.Oracle:
- dataBase = new OracleDataBase();
- break;
- }
- return dataBase.Create();
- }
- }
現在可對這句代碼進行替換了:DataExecutor execObj = new MSSqlExecutor();
替換為:DataExecutor execObj = ExecutorFactory.Create();
至此,問題都解決了,切換資料庫是只需更改DatabaseType為相應的數庫類型。
接下來再考慮下,如果改變資料庫類型也不需要變動程式,能不能實現?
還是利用設定檔,只是此時提供的不是類型字串,而是實際的資料執行者程式集資訊,再利用.NET的天然優勢反射可以實現了。
最終設定檔為:
- <appSettings>
- <add key="ConnStr" value="server=.;uid=sa;password=123456;database=DATA_BASE;max pool size=300"/>
- <add key="DBExecutor" value="FM.DataAccess, FM.DataAccess.MappingExcuter.MSSqlExecutor"></add>
- </appSettings>
改造後的工廠:
- public sealed class ExecutorFactory
- {
- public static DataExecutor Create()
- {
- return Create(null);
- }
- public static DataExecutor Create(string dataBaseTypeKey)
- {
- return Create(dataBaseTypeKey, null);
- }
- public static DataExecutor Create(string dataBaseTypeKey, string connStrKey)
- {
- if (string.IsNullOrEmpty(dataBaseTypeKey))
- {
- dataBaseTypeKey = "DBExecutor";
- }
- string[] sltDataBaseType = ConfigReader.Read(dataBaseTypeKey).Split(',');
- string asselblyName = sltDataBaseType[0];
- string nameSpace = sltDataBaseType[1].Trim();
- Assembly assembly = Assembly.Load(asselblyName);
- DataExecutor execObj = assembly.CreateInstance(nameSpace) as DataExecutor;
- execObj.SetConnectionString(connStrKey);
- return execObj;
- }
- }
到此為止,資料訪問層最終完成,當然這裡還有很多問題有待解決,但其基本架構已形成了,以此為依據,根據業務變化,實現自己的擴充,不斷更新,最終才能真正形成完善的資料訪問層。