對數(shù)據(jù)訪問層第一種實現(xiàn)(Acc+SQL)的重構
對數(shù)據(jù)訪問層種實現(xiàn)(Acc+SQL)的重構
近日的文章基于.NET平臺的分層架構實戰(zhàn)(七)——數(shù)據(jù)訪問層的種實現(xiàn):Access+SQL發(fā)布后,很多朋友對我的程序提出了意見和建議,在這里先謝謝你們。!尤其是金色海洋(jyk),對我的程序提出了很多建設性的意見。
我大體總結了一下,昨天程序的主要缺點有: 1.Connection對象沒有關閉 2.DataReader對象沒有關閉 3.相似代碼太多,造成代碼冗余。
其中點問題,目前還沒有太好的解決方案,主要是因為Connection一旦關閉,DataReader無法讀取了。而且,Connection對象應該會自動在適當?shù)臅r候關閉(通過觀察臨時文件得出),并且在實際運行時并無影響(在功能上),所以這里沒有專門解決。而針對后面兩個問題,我使用了如下解決方案。
對于關閉DataReader的方法,實現(xiàn)起來很簡單,在finally里將他關閉行了。關鍵是如何去處冗余代碼。
經(jīng)過我的分析,數(shù)據(jù)訪問層的操作可以分為三類:不返回數(shù)據(jù),返回單個實體類,返回實體類集合。我將這三種操作的公共部分抽出,寫成三個方法放在AccessDALHelper里,類型不同的問題使用泛型解決。
這樣做有一個難題,是不同實體在由DataReader轉化為實體類時的代碼很不一樣,無法抽出。這里,我使用了Strategy模式解決。具體做法是:首先定義一個由DataReader轉換為實體類的策略接口,然后為不同的實體編寫不同的轉換策略,示意圖如下:可以看出,所有轉換策略都要實現(xiàn)IDataReaderToEntityStrategy接口,并且每個策略都有一個自組合,這是以為他們都要實現(xiàn)Singleton模式。而AccessDALHelper與具體策略無關,僅與接口耦合。
下面來看一下具體代碼:
首先是IDataReaderToEntityStrategy接口
IDataReaderToEntityStrategy1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Text;4usingSystem.Data;5usingSystem.Data.OleDb;67namespaceNGuestBook.AccessDAL8{9/**////10///由DataReader轉換成實體類的策略接口11///12publicinterfaceIDataReaderToEntityStrategy13{14/**////15///將DataReader轉換為實體類,采用泛型16///17///包含數(shù)據(jù)的DataReader對象18///實體類19TDataReaderToEntity(OleDbDataReaderdataReader);}21}
然后以Admin為例,看一下策略的具體實現(xiàn):
1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Web;4usingSystem.Web.Caching;5usingSystem.Configuration;6usingSystem.Data;7usingSystem.Data.OleDb;8usingNGuestBook.Utility;910namespaceNGuestBook.AccessDAL11{12/**////13///Access數(shù)據(jù)庫操作助手14///15publicsealedclassAccessDALHelper16{17/**////18///讀取Access數(shù)據(jù)庫的連接字符串19///首先從緩存里讀取,如果不存在則到配置文件中讀取,并放入緩存///21///Access數(shù)據(jù)庫的連接字符串22privatestaticstringGetConnectionString()23{24if(CacheAccess.GetFromCache("AccessConnectionString")!=null)25{26returnCacheAccess.GetFromCache("AccessConnectionString").ToString();27}28else29{30stringdbPath=ConfigurationManager.AppSettings["AccessPath"];31stringdbAbsolutePath=HttpContext.Current.Server.MapPath(dbPath);32stringconnectionString=ConfigurationManager.AppSettings["AccessConnectionString"];3334CacheDependencyfileDependency=newCacheDependency(HttpContext.Current.Server.MapPath("Web.Config"));35CacheAccess.SaveToCache("AccessConnectionString",connectionString.Replace("{DBPath}",dbAbsolutePath),fileDependency);3637returnconnectionString.Replace("{DBPath}",dbAbsolutePath);38}39}4041/**////42///執(zhí)行SQL語句并且不返回任何值43///44///所執(zhí)行的SQL命令45///參數(shù)集合46publicstaticvoidExecuteSQLNonQuery(stringSQLCommand,OleDbParameter[]parameters)47{48OleDbConnectionconnection=newOleDbConnection(GetConnectionString());49OleDbCommandcommand=newOleDbCommand(SQLCommand,connection);5051for(inti=0;i{69OleDbConnectionconnection=newOleDbConnection(GetConnectionString());70OleDbCommandcommand=newOleDbCommand(SQLCommand,connection);7172for(inti=0;i{69OleDbConnectionconnection=newOleDbConnection(GetConnectionString());70OleDbCommandcommand=newOleDbCommand(SQLCommand,connection);7172for(inti=0;i