成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

數(shù)據(jù)訪(fǎng)問(wèn)層DAL實(shí)現(xiàn)過(guò)程

開(kāi)發(fā) 后端
DAL為數(shù)據(jù)訪(fǎng)問(wèn)層Data Access Layer,主要是對(duì)原始數(shù)據(jù)(數(shù)據(jù)庫(kù)或者文本文件等存放數(shù)據(jù)的形式)的操作層,而不是指原始數(shù)據(jù),也就是說(shuō),是對(duì)數(shù)據(jù)的操作,而不是數(shù)據(jù)庫(kù),具體為業(yè)務(wù)邏輯層或表示層提供數(shù)據(jù)服務(wù)。我們今天將介紹其實(shí)現(xiàn)過(guò)程。

  這里為了演示上簡(jiǎn)單,假設(shè):后臺(tái)數(shù)據(jù)庫(kù)(暫為SqlServer只有用戶(hù)表User與部門(mén)表Department),各表字段相應(yīng)精簡(jiǎn):

User(用戶(hù)表)
Id 主鍵
Name 姓名
DeptId 部門(mén)編號(hào)
其余字段省略......

 

  

Department(部門(mén)表)
Id 主鍵
Name 名稱(chēng)
Desc 部門(mén)描述
其余字段省略......

 

  后臺(tái)數(shù)據(jù)庫(kù):testdb的情況

建立相關(guān)的存儲(chǔ)過(guò)程:

一般我個(gè)人也喜歡ORM轉(zhuǎn)換成實(shí)體對(duì)象(見(jiàn)截圖)

(注意:這里增加了DeptTitle屬性<部門(mén)名稱(chēng)>)

  現(xiàn)在就是訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)SqlServer類(lèi)型,封裝到SqlserverProvider中。如果將來(lái)訪(fǎng)問(wèn)Access數(shù)據(jù)庫(kù),對(duì)應(yīng)訪(fǎng)問(wèn)封裝到AccessProvider中。

  (Provider這里表示數(shù)據(jù)訪(fǎng)問(wèn)提供程序)

  SqlUserProvier專(zhuān)門(mén)實(shí)現(xiàn)對(duì)SqlServer的表User的操作,AccessUserProvider專(zhuān)門(mén)實(shí)現(xiàn)對(duì)Access的表User的操作,很顯然,操作功能都相同(增刪改查<CRUD>),因而對(duì)不同子類(lèi)的相同部分抽象出來(lái),形成父類(lèi)(UserProvider)。

開(kāi)始著手具體子類(lèi)實(shí)現(xiàn):SqlUserProvider:UserProvider

  (上圖數(shù)據(jù)庫(kù)連接串錯(cuò)誤:?jiǎn)卧~integrated才是正確的,***面調(diào)試錯(cuò)誤后改正。)

  我們發(fā)現(xiàn)重載的GetUsers方法,大量代碼重復(fù),進(jìn)行方法重構(gòu)(重復(fù)代碼重構(gòu)為方法GetUsersFromReader)!

  繼續(xù)具體實(shí)現(xiàn)父類(lèi)的抽象方法:GetUserById,發(fā)現(xiàn)該方法的部分代碼與先前的GetUsersFromReader方法中的部分代碼又重復(fù)了!

  發(fā)現(xiàn)上圖紅色部分重復(fù)(該圖GetUserById方法忘記傳遞存儲(chǔ)過(guò)程所需的參數(shù)了),再接著方法重構(gòu),提煉重復(fù)的代碼,避免以后改動(dòng)的多次修改。

  接著編寫(xiě)該類(lèi)后續(xù)的方法(增/刪/改):(可以打開(kāi)VS開(kāi)發(fā)環(huán)境中的<服務(wù)器資源管理器>,連接上對(duì)應(yīng)的數(shù)據(jù)庫(kù)后,看存儲(chǔ)過(guò)程的參數(shù),以免編碼遺忘傳參)

接著也來(lái)看看 類(lèi):AccessUserProvider,見(jiàn)下圖

  上圖GetUsers方法中的查詢(xún)語(yǔ)句沒(méi)有聯(lián)合查詢(xún),后續(xù)會(huì)改動(dòng)。(這里僅僅示范,其似Access是可以類(lèi)似建立查詢(xún)表<后臺(tái)調(diào)用類(lèi)似存儲(chǔ)過(guò)程方式>)

  我們發(fā)現(xiàn)UserProvider的兩個(gè)子類(lèi)的方法GetUserFromReader和GetUsersFromReader有重復(fù)代碼(僅僅是方法的參數(shù)不同) [想辦法抽象出來(lái),放在父類(lèi)中]

  而方法的參數(shù)雖然是SqlDataReader與OleDbDataReader,但是查看定義,看到它們有自己的父類(lèi):DbDataReader。

  public class SqlDataReader : DbDataReader, IDataReader, IDisposable, IDataRecord

  public sealed class OleDbDataReader : DbDataReader

  改寫(xiě)父類(lèi):UserProvider

父類(lèi)的方法加上修飾符protected,是為了確保只有子類(lèi)能夠訪(fǎng)問(wèn)。

  子類(lèi)便可以直接調(diào)用父類(lèi)的方法了(GetUserFromReader和GetUsersFromReader方法),見(jiàn)截圖:

類(lèi)似的完善SqlDepartmentProvider類(lèi)和AccessDepartmentProvider類(lèi)的代碼

  (父類(lèi):DepartmentProvider提供保護(hù)方法GetDeparmentFromReader和GetDepartmentsFromReader)

  每個(gè)具體的子類(lèi)Provider都重復(fù)了屬性:ConnString,所以決定建一個(gè)父類(lèi):DataAccess來(lái)存放該屬性(UserProvider與DepartProvider都繼承自它),實(shí)際上DataAccess還可以包含其它的屬性和共用方法。

  1. namespace抽象工廠(chǎng)模式.DAL  
  2. {  
  3. publicabstractclassDataAccess  
  4. {  
  5. privatestring_connString ="";  
  6. publicstringConnString  
  7. get{ return_connString; } }  
  8. }  

   public abstract class UserProvider:DataAccess

  public abstract class DepartmentProvider:DataAccess

  通常:數(shù)據(jù)庫(kù)連接串的內(nèi)容都是存儲(chǔ)在對(duì)應(yīng)的配置文件中,而不硬編碼。

  桌面應(yīng)用程序—[app.config],web應(yīng)用程序---[web.config],這里以app.config示例,數(shù)據(jù)庫(kù)連接串先按照SqlServer數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)的。

 

  1. <?xml version="1.0" encoding="utf-8" ?> 
  2. <configuration> 
  3. <connectionStrings> 
  4. <add name="DBConnString" 
  5. connectionString="SERVER=.sqlexpress;DATABASE=testdb;INTEGRATED SECURITY=true"/> 
  6. </connectionStrings> 
  7. </configuration> 

  一定要手動(dòng)引用:System.configuration,然后通過(guò)ConfigurationManager類(lèi)來(lái)訪(fǎng)問(wèn)連接串。

  可以想象,根據(jù)數(shù)據(jù)庫(kù)的類(lèi)型不同,實(shí)際底層操控的數(shù)據(jù)提供程序?yàn)镾ql__Provider或是Access__Provider。

  但對(duì)于用戶(hù)調(diào)用者(業(yè)務(wù)邏輯層)只需要操控Provider就可以了。

  假設(shè)我所在城市有兩個(gè)行政分區(qū)(東一區(qū)和西二區(qū)),有一家“真不錯(cuò)”總店[經(jīng)營(yíng)快餐系列的]在這兩個(gè)區(qū)都有連鎖店,對(duì)外統(tǒng)一電話(huà):1111777。

  (設(shè)一個(gè)總機(jī)號(hào)碼當(dāng)然方便了,總不至于將來(lái)開(kāi)了10家分店,對(duì)外公布10個(gè)電話(huà)號(hào)碼,誰(shuí)能記住啊?)

  比如說(shuō):我現(xiàn)在餓了,想吃這家提供的“經(jīng)濟(jì)型快餐(一素<炒萵苣>一湯<豆腐湯>)”,我只要打電話(huà)111177,那邊只需要了解我的地址就可以了。(可以想象:知道了我的地址<就能明白所在行政區(qū),然后公司總店去指派所在區(qū)的分店來(lái)服務(wù)>),對(duì)于客戶(hù)我而言:如何指派哪家分店來(lái)服務(wù),以及經(jīng)濟(jì)型快餐如何制作的,我都不會(huì)關(guān)心的。我只關(guān)心:要好吃,然后要快點(diǎn)(畢竟,餓太久會(huì)受不了的。)

  回到我們的程序:

  UserProvider好比一個(gè)物品蔬菜<萵苣>,DepartmentProvider好比湯菜<豆腐>。Access文件夾[經(jīng)濟(jì)型],SqlServer文件夾[商務(wù)型] (你會(huì)問(wèn)一個(gè)題外問(wèn)題:有葷菜嗎?我的回答是:盡量別吃,如今都是激素喂出來(lái)的<現(xiàn)在人們消耗太快了,以前自然方式半年才能長(zhǎng)大的動(dòng)物,如今1個(gè)月人工方式就用激素喂成了>。吃多了,身體容易得病)。

  只有一個(gè)問(wèn)題:既然BLL(相對(duì)于DAL就是客戶(hù)調(diào)用者)只認(rèn)(UserProvider/DepartmentProvider),又是如何調(diào)用實(shí)際其作用的子類(lèi)呢?

  這就需要用到設(shè)計(jì)模式中的<簡(jiǎn)單工廠(chǎng)模式> (具體選擇哪個(gè)子類(lèi)實(shí)際上用父類(lèi)來(lái)完成<根據(jù)客戶(hù)配置需求>)

當(dāng)然這里的配置文件:數(shù)據(jù)庫(kù)連接串和providerType需要匹配好。

  父類(lèi):UserProvider我們提供靜態(tài)的Instance,來(lái)決定實(shí)際的子類(lèi)(SqlUserProvider或者AccessUserProvider,根據(jù)配置文件的ProviderType的value來(lái)定)

  如果將來(lái)出現(xiàn)了OracleUserProvider/DB2UserProvider/MySqlUserProvider/XmlUserProvider,這個(gè)藍(lán)色框框仍然需要增加case分支。這就不好了,需要再編碼(修改),好的設(shè)計(jì)方式應(yīng)該是對(duì)擴(kuò)展開(kāi)放,對(duì)修改封閉。而且這里羅列出了所有的具體子類(lèi)Provider,其實(shí)只需要一個(gè)子類(lèi)Provider,但是其他的子類(lèi)Provider也被迫出現(xiàn)在一起<大雜燴>(其實(shí)子類(lèi)之間出現(xiàn)了耦合) 所以這種方式不可取,需要解決。

  這里用反射的方式來(lái)解決這個(gè)問(wèn)題。

  首先約束:ProviderType的賦值需要規(guī)范,只能從(Sql/Access/DB2/MySql/Xml)選擇一個(gè)呢。可以發(fā)現(xiàn):實(shí)際的子類(lèi)名:ProviderType的值+“UserProvider”。

 

  1. staticpublicUserProvider Instance  
  2. {  
  3. get 
  4. {  
  5. if(_instance == null)  
  6. {  
  7. stringproviderTypeName=ConfigurationManager.AppSettings["ProviderType"]  
  8. +"UserProvider";  
  9. _instance =  
  10. Activator.CreateInstance(Type.GetType(providerTypeName)) asUserProvider;  
  11. }  
  12. return_instance;  
  13. }  

 

  如果:你的DAL是單獨(dú)用程序集方式建立的項(xiàng)目(類(lèi)庫(kù)),請(qǐng)使用Assembly.Load等方式,這里由于是以文件夾方式組織的(DAL文件夾)<用Activator.CreateInstance可以O(shè)K.>

  以后客戶(hù)端(BLL)調(diào)用的時(shí)候:比如刪除用戶(hù)表的記錄,就可以如下調(diào)用了:

  UserProvider.Instance.DeleteUser(id)了。//這里BLL已經(jīng)不知道是由哪個(gè)子類(lèi)(如SqlUserProvider)來(lái)實(shí)際工作的。

  進(jìn)行一下測(cè)試,看是否運(yùn)行正常!

  發(fā)現(xiàn)錯(cuò)誤:一:數(shù)據(jù)庫(kù)連接串需要修改:

二:文件夾SqlServer改成Sql。以前的命名空間對(duì)應(yīng)改動(dòng)下:

  namespace抽象工廠(chǎng)模式.DAL.Provider.Sql

  {

  publicclassSqlDepartmentProvider:DepartmentProvider

  ………………………………………….

  namespace抽象工廠(chǎng)模式.DAL.Provider.Sql

  {

  publicclassSqlUserProvider:UserProvider

  ………………………………………………………….

  三:Type.GetType(需要完整的限定名)

測(cè)試通過(guò):但發(fā)現(xiàn)沒(méi)有DeptTitle數(shù)據(jù),查找錯(cuò)誤發(fā)現(xiàn)

 

  1.   publicUser(intid, stringname, intdeptId, stringdeptTitle)  
  2.   {  
  3.   this.Id = id;  
  4.   this.Name = name;  
  5.   this.DeptId = deptId;  
  6.   this.DeptTitle = deptTitle; //DeptTitle;  
  7.   } 

 

附上:AccessUserProvider的代碼如下:

 

AccessUserProvider代碼

 

  1. usingSystem;  
  2. usingSystem.Collections.Generic;  
  3. usingSystem.Text;  
  4. usingSystem.Data;  
  5. usingSystem.Data.OleDb;  
  6. using抽象工廠(chǎng)模式.DAL;  
  7. using抽象工廠(chǎng)模式.DAL.Entity;  
  8. namespace抽象工廠(chǎng)模式.DAL.Provider.Access  
  9. {  
  10. publicclassAccessUserProvider:UserProvider  
  11. {  
  12. publicoverrideList<User> GetUsers()  
  13. {  
  14. using(OleDbConnection conn = newOleDbConnection(ConnString))  
  15. {  
  16. vardbcmd = conn.CreateCommand();  
  17. dbcmd.CommandText = "GetUsers";  
  18. dbcmd.CommandType = CommandType.StoredProcedure;  
  19. conn.Open();  
  20. returnGetUsersFromReader(dbcmd.ExecuteReader());  
  21. }  
  22. }  
  23. publicoverrideList<User> GetUsers(intdeptId)  
  24. {  
  25. using(OleDbConnection conn = newOleDbConnection(ConnString))  
  26. {  
  27. vardbcmd = conn.CreateCommand();  
  28. dbcmd.CommandText = "GetUsersByDepartmentId";  
  29. dbcmd.CommandType = CommandType.StoredProcedure;  
  30. dbcmd.Parameters.Add("@DeptId", OleDbType.Integer).Value = deptId;  
  31. conn.Open();  
  32. returnGetUsersFromReader(dbcmd.ExecuteReader());  
  33. }  
  34. }  
  35. publicoverrideUser GetUserById(intid)  
  36. {  
  37. using(OleDbConnection conn = newOleDbConnection(ConnString))  
  38. {  
  39. vardbcmd = conn.CreateCommand();  
  40. dbcmd.CommandText = "GetUserById";  
  41. dbcmd.CommandType = CommandType.StoredProcedure;  
  42. dbcmd.Parameters.Add("@Id", OleDbType.Integer).Value =id ;  
  43. conn.Open();  
  44. returnGetUserFromReader(dbcmd.ExecuteReader());  
  45. }  
  46. }  
  47. publicoverrideboolDeleteUser(intid)  
  48. {  
  49. using(OleDbConnection conn = newOleDbConnection(ConnString))  
  50. {  
  51. OleDbCommand cmd = newOleDbCommand(  
  52. "delete from [user] where Id="+ id, conn);  
  53. conn.Open();  
  54. returncmd.ExecuteNonQuery() == 1;  
  55. }  
  56. }  
  57. publicoverrideintInsertUser(User user)  
  58. {  
  59. using(OleDbConnection conn = newOleDbConnection(ConnString))  
  60. {  
  61. OleDbCommand cmd = newOleDbCommand(  
  62. @"insert into [user](name,deptId) values(@id,@name);68select max(id) from [user] as newid",conn);  
  63. cmd.Parameters.Add("@id", OleDbType.Integer).Value = user.Id;  
  64. cmd.Parameters.Add("@name", OleDbType.VarChar).Value = user.Name;  
  65. conn.Open();  
  66. return(int)cmd.ExecuteScalar();  
  67. }  
  68. }  
  69. publicoverrideboolUpdateUser(User user)  
  70. {  
  71. using(OleDbConnection conn = newOleDbConnection(ConnString))  
  72. {  
  73. OleDbCommand cmd = newOleDbCommand(  
  74. "update [user] set name=@name,deptId=@deptid where Id=@id", conn);  
  75. cmd.Parameters.Add("@name", OleDbType.Integer).Value = user.Name;  
  76. cmd.Parameters.Add("@deptid", OleDbType.Integer).Value = user.DeptId;  
  77. cmd.Parameters.Add("@id", OleDbType.Integer).Value = user.Id;  
  78. conn.Open();  
  79. returncmd.ExecuteNonQuery() == 1;  
  80. }  
  81. }  
  82. }  

 

  后臺(tái)的testdb.mdb截圖:

原文鏈接:http://www.cnblogs.com/netxiaochong/archive/2012/01/10/2318119.html

【編輯推薦】

  1. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之開(kāi)卷有益
  2. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)建模1
  3. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)建模2
  4. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)建模3
  5. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)建模4
  6. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)設(shè)計(jì)規(guī)范與原則1
  7. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)設(shè)計(jì)規(guī)范與原則2
  8. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之業(yè)務(wù)邏輯層
  9. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之表現(xiàn)層
  10. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之服務(wù)層
  11. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之?dāng)?shù)據(jù)訪(fǎng)問(wèn)層
責(zé)任編輯:彭凡 來(lái)源: 博客園
相關(guān)推薦

2009-08-19 10:54:42

ASP.NET數(shù)據(jù)訪(fǎng)問(wèn)

2011-05-07 12:56:39

數(shù)據(jù)訪(fǎng)問(wèn)

2011-03-29 09:15:28

通用數(shù)據(jù)訪(fǎng)問(wèn)層

2009-09-04 18:00:54

C#數(shù)據(jù)訪(fǎng)問(wèn)層

2012-06-07 10:53:08

架構(gòu)設(shè)計(jì)數(shù)據(jù)訪(fǎng)問(wèn)層設(shè)計(jì)原則

2010-03-02 11:15:34

PDA訪(fǎng)問(wèn)WCF

2009-08-13 14:59:00

C#數(shù)據(jù)訪(fǎng)問(wèn)層

2011-05-05 14:33:34

數(shù)據(jù)訪(fǎng)問(wèn)層

2011-05-10 16:44:43

數(shù)據(jù)訪(fǎng)問(wèn)層

2012-02-03 09:44:33

.NET

2009-07-24 14:15:51

數(shù)據(jù)訪(fǎng)問(wèn)層

2009-07-24 13:25:43

創(chuàng)建數(shù)據(jù)訪(fǎng)問(wèn)層

2009-07-24 13:45:28

添加參數(shù)化

2009-08-04 10:17:55

ASP.NET SqlASP.NET數(shù)據(jù)訪(fǎng)問(wèn)

2009-09-28 13:29:41

加載過(guò)程Hibernate訪(fǎng)問(wèn)

2009-07-24 14:23:16

定制編碼DAL

2009-07-24 13:25:31

ASP.NET 2.0數(shù)據(jù)訪(fǎng)問(wèn)層(DAL)

2012-08-15 11:03:18

框架項(xiàng)目

2009-07-24 14:02:39

ASP.NET 2.0

2010-09-28 12:59:45

JavaScriptDOM
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩欧美三级电影 | 在线欧美小视频 | 嫩呦国产一区二区三区av | 欧美a∨ | 亚洲精品欧美一区二区三区 | 色呦呦网站 | 亚洲综合在线视频 | 国产欧美精品区一区二区三区 | 噜久寡妇噜噜久久寡妇 | 欧美精品一区二区三区在线播放 | 青草视频在线 | 日韩中文一区二区 | 精品中文字幕一区二区三区 | 精品中文字幕久久 | 国产精品日韩在线观看一区二区 | 二区欧美 | av资源在线看 | 中文成人在线 | 亚洲97 | 男人视频网站 | 久久一二| 亚洲97 | 日韩国产在线观看 | 日韩成人 | 超碰人人插 | 五月婷婷视频 | 国内久久精品 | 国产精品毛片一区二区三区 | 成人在线视频免费看 | 欧美中文字幕一区二区 | 一区中文 | 亚洲精品一区二区三区免 | 男女视频免费 | 亚洲视频一区在线 | 91麻豆产精品久久久久久夏晴子 | 黄色一级大片在线免费看产 | 麻豆一区二区三区 | 黄色网络在线观看 | 欧美国产日韩在线 | 中文字幕视频在线看5 | 奇米影视首页 |