3層數據訪問架構(部分)

1、實體類是現實css

實體在計算機中的表示。 它貫穿於整個架構, 負擔着在各層次及模塊間傳遞數
據的職責。通常來講,實體類能夠分爲「貧血實體類」和「充血實體類」,前者僅僅保存實體的
屬性,然後者還包含一些體間的關係與邏輯。咱們在這個 Demo 中用的實體類將是「貧血
體類」。
大多狀況下, 實體類和數據庫中的表 (這裏指體表, 不包括表示多對多對應的關係表)
是一一對應的, 但這並非一個限制,在複雜的數據庫設計中, 有可能出現一個實體類對應
多個表,或者交叉對應的狀況。在本文的 Demo 中,實體類和表是一一對應的,而且體
類中的屬性和表中的字段也是對應的。
在看實體類的代碼前,先看一下系統的工程結構。數據庫

image
如上圖所示,在初始階段,整個系統包括 6 個工程,它們的職責是這樣的:
Web——表示層
Entity——存放實體類
Factory——存放和依賴注入及 IoC 相關的類
IBLL——存放業務邏輯層接口族
IDAL——存放數據訪問層接口族
Utility——存放各類工具類及輔助類
3
這只是一個初期架構, 主要是將整個系統搭一個框架, 在後續開發中, 將會有其餘工程
被陸陸續續添加進來。
咱們的實體類將放在 Entity 工程下,這裏包括三個文件:AdminInfo.cs,MessageInfo.
cs,CommentInfo.cs,分別是管理員實體類、留言體類和評論實體類。具體代碼以下:
AdminInfo.cs:設計模式

using  System;
namespace  NGuestBook.Entity
{
    /**////  <summary>
    ///  體類-管理員
    ///  </summary>
    [Serializable]
    public  class  AdminInfo
    {
        private  int  id;
        4
            private  string  name;
        private  string  password;
        public  int  ID
        {
            get  {  return  this.id;  }
            set  {  this.id  =  value;  }
        }
        public  string  Name
        {
            get  {  return  this.name;  }
            set  {  this.name  =  value;  }
        }
        5
            public  string  Password
        {
            get  {  return  this.password;  }
            set  {  this.password  =  value;  }
        }
    }
}
MessageInfo.cs:
    MessageInfo
    using  System;
namespace  NGuestBook.Entity
{
    6
        /**////  <summary>
        ///  體類-留言
        ///  </summary>
        [Serializable]
        public  class  MessageInfo
    {
        private  int  id;
        private  string  guestName;
        private  string  guestEmail;
        private  string  content;
        private  DateTime  time;
        private  string  reply;
        private  string  isPass;
        7
            public  int  ID
        {
            get  {  return  this.id;  }
            set  {  this.id  =  value;  }
        }
        public  string  GuestName
        {
            get  {  return  this.guestName;  }
            set  {  this.guestName  =  value;  }
        }
        public  string  GuestEmail
        {
            8
                get  {  return  this.guestEmail;  }
            set  {  this.guestEmail  =  value;  }
        }
        public  string  Content
        {
            get  {  return  this.content;  }
            set  {  this.content  =  value;  }
        }
        public  DateTime  Time
        {
            get  {  return  this.time;  }
            set  {  this.time  =  value;  }
        }
        9
            public  string  Reply
        {
            get  {  return  this.reply;  }
            set  {  this.reply  =  value;  }
        }
        public  string  IsPass
        {
            get  {  return  this.isPass;  }
            set  {  this.isPass  =  value;  }
        }
    }
}

CommentInfo.cs:
CommentInfo 緩存

using  System;
namespace  NGuestBook.Entity
{
    /**////  <summary>
    ///  體類-評論
    ///  </summary>
    [Serializable]
    public  class  CommentInfo
    {
        private  int  id;
        private  string  content;
        private  DateTime  time;
        11
            private  int  message;
        public  int  ID
        {
            get  {  return  this.id;  }
            set  {  this.id  =  value;  }
        }
        public  string  Content
        {
            get  {  return  this.content;  }
            set  {  this.content  =  value;  }
        }
        public  DateTime  Time
            12
        {
            get  {  return  this.time;  }
            set  {  this.time  =  value;  }
        }
        public  int  Message
        {
            get  {  return  this.message;  }
            set  {  this.message  =  value;  }
        }
    }
}

你們能夠看出, 實體類的代碼很簡單, 僅僅是負責體的表示和數據的傳遞, 不包含任
何邏輯性內容。下篇將介紹接口的設計。 架構

接口的設計與現
接下來,將進行接口的設計。這裏包括數據訪問層接口和業務邏輯層接口。在分層架構中,
接口扮演着常重要的角色,它不但直接決定了各層中的各個操做類須要現何種操做,而
且它明確了各個層次的職責。接口也是系統實現依賴注入機制不可缺乏的部分。
本項目的接口設計將按以下順序進行:
1.首先由前文的需求分析,列出主要的 UI 部分。
2.分析各個 UI 須要什麼業務邏輯支持,從而肯定業務邏輯層接口。
3.分析業務邏輯層接口須要何種數據訪問操做,從而肯定數據訪問層接口。
另外,爲保證徹底的面向對象特性,接口之間的數據傳遞主要靠實體類或實體類集合,
禁止使用 DataTable 等對象傳遞數據。
由需求分析,列出主要 UI
需求分析部分,請參看基於.NET 平臺的分層架構實戰(二)——需求分析與數據庫設
計  。有需求分析,能夠列出系統中主要應包括如下 UI:
UI01——主頁面,列出所有的留言及相應評論,支持分頁顯示。留言按發表時間逆序
顯示, 評論緊跟在相應留言下。 管理員能夠經過相應連接對留言執行經過驗證、 刪除、 回覆
以及對評論進行刪除操做。遊客可經過相應鏈接進入發表留言評論頁面。
UI02——發表留言頁面,供遊客發表新留言。
UI03——發表評論頁面,供遊客發表評論。
UI04——回覆留言頁面,供管理員回覆留言。
UI05——管理員登陸頁面。
UI06——管理員修改我的密碼的頁面。
UI07——超級管理員登陸後的頁面,主要提供管理員列表。能夠經過相應連接將指定
管理員刪除。
UI08——添加新管理員的頁面。
UI09——操做成功完成後的跳轉提示頁面。
UI10——系統出現異常時顯示友好出錯信息的頁面。
由 UI 識別業務邏輯操做
UI01:按分頁取得留言,按指定留言取得所有評論,將指定留言經過驗證,將指定留
言刪除,將指定評論刪除
UI02:添加新留言
UI03:添加新評論
UI04:回覆留言
UI05:管理員登陸
UI06:修改管理員密碼
UI07:取得所有管理員信息,刪除管理員
UI08:添加新管理員
通過整理,可得如下接口操做:
IAdminBLL:Add(添加管理員),Remove(刪除管理員),ChangePassword(修
改管理員密碼),Login(管理員登陸),GetAll(取得所有管理員)
IMessageBLL:Add(添加留言),Remove(刪除留言),Revert(回覆留言),Pa
ss(將留言經過驗證),GetByPage(按分頁取得留言)
ICommentBLL:Add(添加評論),Remove(刪除評論),GetByMessage(按留言
取得所有評論)
這三個接口文件都放在 IBLL 工程下,具體代碼以下:app

IAdminBLL.cs:
IAdminBLL 框架

using  System;
using  System.Collections.Generic;
using  System.Text;
using  NGuestBook.Entity;
namespace  NGuestBook.IBLL
{
    /**////  <summary>
    ///  業務邏輯層接口-管理員
    ///  </summary>
    public  interface  IAdminBLL
        16
    {
        /**////  <summary>
        ///  添加管理員
        ///  </summary>
        ///  <param  name="admin">新管理員體類</param>
        ///  <returns>是否成功</returns>
        bool  Add(AdminInfo  admin);
        /**////  <summary>
        ///  刪除管理員
        ///  </summary>
        ///  <param  name="id">欲刪除的管理員的 ID</param>
        ///  <returns>是否成功</returns>
        bool  Remove(int  id);
        17
            /**////  <summary>
            ///  修改管理員密碼
            ///  </summary>
            ///  <param  name="id">欲修改密碼的管理員的 ID</param>
            ///  <param  name="password">新密碼</param>
            ///  <returns>是否成功</returns>
            bool  ChangePassword(int  id,string  password);
        /**////  <summary>
        ///  管理員登陸
        ///  </summary>
        ///  <param  name="name">管理員登陸名</param>
        ///  <param  name="password">管理員密碼</param>
        ///  <returns>若是登陸成功,則返回相應管理員的實體類,不然返回 null</returns>
        18
            AdminInfo  Login(string  name,string  password);
        /**////  <summary>
        ///  取得所有管理員信息
        ///  </summary>
        ///  <returns>管理員體類集合</returns>
        IList<AdminInfo>  GetAll();
    }
}

IMessageBLL.cs:
IMessageBLL 數據庫設計

using  System;
using  System.Collections.Generic;
using  System.Text;
 
    using  NGuestBook.Entity;
namespace  NGuestBook.IBLL
{
    /**////  <summary>
    ///  業務邏輯層接口-留言
    ///  </summary>
    public  interface  IMessageBLL
    {
        /**////  <summary>
        ///  添加留言
        ///  </summary>
        ///  <param  name="message">新留言體類</param>
        ///  <returns>是否成功</returns>
 
            bool  Add(MessageInfo  message);
        /**////  <summary>
        ///  刪除留言
        ///  </summary>
        ///  <param  name="id">欲刪除的留言的 ID</param>
        ///  <returns>是否成功</returns>
        bool  Remove(int  id);
        /**////  <summary>
        ///  回覆留言
        ///  </summary>
        ///  <param  name="id">要回復的留言的 ID</param>
        ///  <param  name="reply">回覆信息</param>
        ///  <returns>是否成功</returns>
 
            bool  Revert(int  id,  string  reply);
        /**////  <summary>
        ///  將留言經過驗證
        ///  </summary>
        ///  <param  name="id">經過驗證的留言的 ID</param>
        ///  <returns>是否成功</returns>
        bool  Pass(int  id);
        /**////  <summary>
        ///  按分頁取得留言信息
        ///  </summary>
        ///  <param  name="pageSize">每頁顯示幾條留言</param>
        ///  <param  name="pageNumber">當前頁碼</param>
        ///  <returns>留言體類集合</returns>
 
            IList<MessageInfo>  GetByPage(int  pageSize,int  pageNumber);
    }
}

ICommentBLL.cs
ICommentBLL ide

using  System;
using  System.Collections.Generic;
using  System.Text;
using  NGuestBook.Entity;
namespace  NGuestBook.IBLL
{
    /**////  <summary>
    ///  業務邏輯層接口-評論
    ///  </summary>
 
        public  interface  ICommentBLL
    {
        /**////  <summary>
        ///  添加評論
        ///  </summary>
        ///  <param  name="comment">新評論體類</param>
        ///  <returns>是否成功</returns>
        bool  Add(CommentInfo  comment);
        /**////  <summary>
        ///  刪除評論
        ///  </summary>
        ///  <param  name="id">欲刪除的評論的 ID</param>
        ///  <returns>是否成功</returns>
 
            bool  Remove(int  id);
        /**////  <summary>
        ///  取得指定留言的所有評論
        ///  </summary>
        ///  <param  name="messageId">指定留言的 ID</param>
        ///  <returns>評論體類集合</returns>
        IList<CommentInfo>  GetByMessage(int  messageId);
    }
}

由業務邏輯肯定數據訪問操做
IAdminBLL 須要的數據訪問操做:插入管理員,刪除管理員,更新管理員信息,按 ID
取得管理員信息,按登陸名與密碼取得管理員,取得所有管理員
IMessageBLL 須要的數據訪問操做:插入留言,刪除留言,更新留言信息,按 ID 取得留言
信息,按分頁取得留言
ICommentBLL 須要的數據訪問操做:插入評論,刪除評論,按留言取得所有評論
25
另外,添加管理員時須要驗證是否存在同名管理員,因此須要添加一個「按登陸名取得
管理員」。
對以上操做進行整理,的以下接口操做:
IAdminDAL:Insert,Delete,Update,GetByID,GetByNameAndPassword,GetAll
IMessageDAL:Insert,Delete,Update,GetByID,GetByPage
ICommentDAL:Insert,Delete,GetByMessage
這三個接口文件放在 IDAL 工程下,具體代碼以下:
IAdminDAL.cs:
IAdminDAL 工具

using  System;
using  System.Collections.Generic;
using  System.Text;
using  NGuestBook.Entity;
namespace  NGuestBook.IDAL
{
    /**////  <summary>
    ///  數據訪問層接口-管理員
 
        ///  </summary>
        public  interface  IAdminDAL
    {
        /**////  <summary>
        ///  插入管理員
        ///  </summary>
        ///  <param  name="admin">管理員體類</param>
        ///  <returns>是否成功</returns>
        bool  Insert(AdminInfo  admin);
        /**////  <summary>
        ///  刪除管理員
        ///  </summary>
        ///  <param  name="id">欲刪除的管理員的 ID</param>
 
            ///  <returns>是否成功</returns>
            bool  Delete(int  id);
        /**////  <summary>
        ///  更新管理員信息
        ///  </summary>
        ///  <param  name="admin">管理員體類</param>
        ///  <returns>是否成功</returns>
        bool  Update(AdminInfo  admin);
        /**////  <summary>
        ///  按 ID 取得管理員信息
        ///  </summary>
        ///  <param  name="id">管理員 ID</param>
 
            ///  <returns>管理員體類</returns>
            AdminInfo  GetByID(int  id);
        /**////  <summary>
        ///  按管理員名取得管理員信息
        ///  </summary>
        ///  <param  name="name">管理員名</param>
        ///  <returns>管理員體類</returns>
        AdminInfo  GetByName(string  name);
        /**////  <summary>
        ///  按用戶名及密碼取得管理員信息
        ///  </summary>
        ///  <param  name="name">用戶名</param>
        ///  <param  name="password">密碼</param>
 
            ///  <returns>管理員體類,不存在時返回 null</returns>
            AdminInfo  GetByNameAndPassword(string  name,string  password);
        /**////  <summary>
        ///  取得所有管理員信息
        ///  </summary>
        ///  <returns>管理員體類集合</returns>
        IList<AdminInfo>  GetAll();
    }
}

IMessageDAL.cs:
IMessageDAL

using  System;
using  System.Collections.Generic;
using  System.Text;
using  NGuestBook.Entity;
 
 
    namespace  NGuestBook.IDAL
{
    /**////  <summary>
    ///  數據訪問層接口-留言
    ///  </summary>
    public  interface  IMessageDAL
    {
        /**////  <summary>
        ///  插入留言
        ///  </summary>
        ///  <param  name="message">留言體類</param>
        ///  <returns>是否成功</returns>
        bool  Insert(MessageInfo  message);
 
        /**////  <summary>
        ///  刪除留言
        ///  </summary>
        ///  <param  name="id">欲刪除的留言的 ID</param>
        ///  <returns>是否成功</returns>
        bool  Delete(int  id);
 
        /**////  <summary>
        ///  更新留言信息
        ///  </summary>
        ///  <param  name="message">留言體類</param>
        ///  <returns>是否成功</returns>
        bool  Update(MessageInfo  message);
 
 
        /**////  <summary>
        ///  按 ID 取得留言信息
        ///  </summary>
        ///  <param  name="id">留言 ID</param>
        ///  <returns>留言體類</returns>
        MessageInfo  GetByID(int  id);
 
        /**////  <summary>
        ///  按分頁取得留言信息
        ///  </summary>
        ///  <param  name="pageSize">每頁顯示幾條留言</param>
        ///  <param  name="pageNumber">當前頁碼</param>
        ///  <returns>留言體類集合</returns>
        IList<MessageInfo>  GetByPage(int  pageSize,int  pageNumber);
    }
}
 

ICommentDAL.cs:
ICommentDAL

using  System;
using  System.Collections.Generic;
using  System.Text;
using  NGuestBook.Entity;
 
namespace  NGuestBook.IDAL
{
 
    /**////  <summary>
    ///  數據訪問層接口-評論
    ///  </summary>
    public  interface  ICommentDAL
    {
        /**////  <summary>
        ///  插入評論
        ///  </summary>
        ///  <param  name="comment">評論體類</param>
        ///  <returns>是否成功</returns>
        bool  Insert(CommentInfo  comment);
 
        /**////  <summary>
        ///  刪除評論
        ///  </summary>
        ///  <param  name="id">欲刪除的評論的 ID</param>
        ///  <returns>是否成功</returns>
        bool  Delete(int  id);
 
        /**////  <summary>
        ///  取得指定留言的所有評論
        ///  </summary>
        ///  <param  name="messageId">指定留言的 ID</param>
        ///  <returns>評論體類集合</returns>
        IList<CommentInfo>  GetByMessage(int  messageId);
    }
}

依賴注入
咱們設計的分層架構, 層與層之間應該是鬆散耦合的。 由於是單向單一調用, 因此,這裏的
「鬆散耦合」實際是指上層類不能具體依賴於下層類,而應該依賴於下層提供的一個接口。這
樣, 上層類不能直接實例化下層中的類,而只持有接口, 至於接口所指變量最終到底是哪一
個類,則由依賴注入機制決定。
34
之因此這樣作,是爲了實現層與層之間的「可替換」式設計,例如,如今須要換一種方式
現數據訪問層, 只要這個實現遵循了前面定義的數據訪問層接口, 業務邏輯層和表示層不
須要作任何改動,只須要改一下配置文件系統便可正常運行。另外,基於這種結構的系統,
還能夠現並行開發。 即不一樣開發人員能夠專一於本身的層次, 只有接口被定義好了, 開發
出來的東西就能夠無縫鏈接。
在 J2EE 平臺上,主要使用 Spring 框架實現依賴注入。這裏,咱們將本身作一個依賴
注入容器。
依賴注入的理論基礎是 Abstract  Factory 設計模式,這裏結合具體實例簡單介紹一下。

image

上圖以數據訪問層爲例, 展現了 Abstract  Factory 模式的應用。 如圖,現假設有針對 A
ccess 和 SQLServer 兩種數據庫的數據訪問層,它們都現了數據訪問層接口。每一個數據
訪問層有本身的工廠,全部工廠都現自 IDALFactory 接口。而客戶類(這裏就是業務邏
輯層類)僅與工廠接口、數據訪問層接口耦合,而與具體類無關,這樣,只要經過配置文件
肯定實例化哪一個工廠,就能夠獲得不一樣的數據訪問層。
然而, 這種設計雖然可行, 可是代碼比較冗餘, 由於這樣須要爲數據訪問層的每個實
現編寫一個工廠,業務邏輯層也同樣。在之前,咱們毫無辦法,可是,.NET 平臺引入的反
射機制, 給咱們提供了一種解決方案。 使用反射, 每一個層只須要一個工廠, 而後經過從配置
文件中讀出程序集的名稱, 動態加載相應類。 另外,爲了提升依賴注入機制的效率,這裏引
入緩存機制。下面來看具體實現。
配置
首先,須要在 Web 工程的 Web.config 文件的<appSettings>節點下添加以下兩個項:
<add  key="DAL"  value=""/>
<add  key="BLL"  value=""/>
這兩個配置選項分別存儲要應用的數據訪問和也業務邏輯層的程序集名稱。value 目前
是空,是由於目前尚未各個層次的具體實現。
現緩存操做輔助類
爲現緩存操做, 咱們將緩存操做封裝成一個輔助類, 放在 Utility 工程下, 具體代碼如
下:
CacheAccess.cs:
CacheAccess

using  System;
using  System.Web;
using  System.Web.Caching;
 
namespace  NGuestBook.Utility
{
    /**////  <summary>
 
    ///  輔助類,用於緩存操做
    ///  </summary>
    public  sealed  class  CacheAccess
    {
        /**////  <summary>
        ///  將對象加入到緩存中
        ///  </summary>
        ///  <param  name="cacheKey">緩存鍵</param>
        ///  <param  name="cacheObject">緩存對象</param>
        ///  <param  name="dependency">緩存依賴項</param>
        public  static  void  SaveToCache(string  cacheKey,  object  cacheObject,  CacheDe
 
                                          {
                                              Cache  cache  =  HttpRuntime.Cache;
                                              cache.Insert(cacheKey,  cacheObject,  dependency);
                                          }
 
                                          /**////  <summary>
 
                                          ///  </summary>
                                          ///  <param  name="cacheKey">緩存鍵</param>
                                          ///  <returns>獲取的緩存對象</returns>
                                          public  static  object  GetFromCache(string  cacheKey)
                                          {
                                              Cache  cache  =  HttpRuntime.Cache;
 
                                              return  cache[cacheKey];
                                          }
 
        }
}

封裝依賴注入代碼
由於不少依賴注入代碼常類似,爲了減小重複性代碼, 咱們將可複用的代碼先封裝在
一個類中。具體代碼以下(這個類放在 Factory 工程下):
DependencyInjector.cs:
DependencyInjector

using  System;
using  System.Configuration;
using  System.Reflection;
using  System.Web;
using  System.Web.Caching;
using  NGuestBook.Utility;
 
 
{
    /**////  <summary>
    ///  依賴注入提供者
    ///  使用反射機制現
    ///  </summary>
    public  sealed  class  DependencyInjector
    {
        /**////  <summary>
        ///  取得數據訪問層對象
        ///  首先檢查緩存中是否存在,若是不存在,則利用反射機制返回對象
        ///  </summary>
 
        ///  <param  name="className">數據訪問類名稱</param>
        ///  <returns>數據訪問層對象</returns>
        public  static  object  GetDALObject(string  className)
        {
            /**////  <summary>
            ///  取得數據訪問層名稱,首先檢查緩存,不存在則到配置文件中讀取
 
            ///  </summary>
            object  dal  =  CacheAccess.GetFromCache("DAL");
            if  (dal  ==  null)
            {
                CacheDependency  fileDependency  =  new  CacheDependency(HttpConte
                                                                         .Current.Server.MapPath("Web.Config"));
                dal  =  ConfigurationManager.AppSettings["DAL"];
                CacheAccess.SaveToCache("DAL",  dal,  fileDependency);
            }
 
            /**////  <summary>
            ///  取得數據訪問層對象
            ///  </summary>
            string  dalName  =  (string)dal;
            string  fullClassName  =  dalName  +  "."  +  className;
            object  dalObject  =  CacheAccess.GetFromCache(className);
            if  (dalObject  ==  null)
            {
                CacheDependency  fileDependency  =  new  CacheDependency(HttpConte
                                                                         .Current.Server.MapPath("Web.Config"));
                dalObject  =  Assembly.Load(dalName).CreateInstance(fullClassName);
 
                CacheAccess.SaveToCache(className,  dalObject,  fileDependency);
            }
 
            return  dalObject;
        }
 
        /**////  <summary>
        ///  取得業務邏輯層對象
        ///  首先檢查緩存中是否存在,若是不存在,則利用反射機制返回對象
        ///  </summary>
        ///  <param  name="className">業務邏輯類名稱</param>
        ///  <returns>業務邏輯層對象</returns>
        public  static  object  GetBLLObject(string  className)
        {
            /**////  <summary>
            ///  取得業務邏輯層名稱,首先檢查緩存,不存在則到配置文件中讀取
            ///  緩存依賴項爲 Web.Config 文件
            ///  </summary>
            object  bll  =  CacheAccess.GetFromCache("BLL");
            if  (bll  ==  null)
            {
                CacheDependency  fileDependency  =  new  CacheDependency(HttpConte
                                                                         .Current.Server.MapPath("Web.Config"));
                bll  =  ConfigurationManager.AppSettings["BLL"];
                CacheAccess.SaveToCache("BLL",  bll,  fileDependency);
            }
 
            /**////  <summary>
 
            ///  取得業務邏輯層對象
            ///  </summary>
            string  bllName  =  (string)bll;
            string  fullClassName  =  bllName  +  "."  +  className;
            object  bllObject  =  CacheAccess.GetFromCache(className);
            if  (bllObject  ==  null)
            {
                CacheDependency  fileDependency  =  new  CacheDependency(HttpConte
                                                                         .Current.Server.MapPath("Web.Config"));
                bllObject  =  Assembly.Load(bllName).CreateInstance(fullClassName);
                CacheAccess.SaveToCache(className,  bllObject,  fileDependency);
            }
 
            return  bllObject;
        }
    }
}

現工廠
下面使用兩個輔助類,實現數據訪問層工廠和業務邏輯層工廠。
DALFactory.cs
DALFactory

using  System;
using  NGuestBook.IDAL;
#VALUE!
namespace  NGuestBook.Factory
{
    #VALUE!
    /**////  <summary>
    ///  數據訪問層工廠,用於獲取相應的數據訪問層對象
    ///  使用 Abstract  Factory 設計模式+Facace 設計模式+反射機制+緩存機制設計
    ///  </summary>
    public  sealed  class  DALFactory
    {
        /**////  <summary>
        ///  獲取管理員數據訪問層對象
        ///  </summary>
        ///  <returns>管理員數據訪問層對象</returns>
        public  static  IAdminDAL  CreateAdminDAL()
        {
            return  (IAdminDAL)DependencyInjector.GetDALObject("AdminDAL");
        }
        #VALUE!
        /**////  <summary>
        ///  獲取留言數據訪問層對象
        ///  </summary>
        ///  <returns>留言數據訪問層對象</returns>
        public  static  IMessageDAL  CreateMessageDAL()
        {
            return  (IMessageDAL)DependencyInjector.GetDALObject("MessageDAL");
        }
        #VALUE!
        /**////  <summary>
        ///  獲取評論數據訪問層對象
        ///  </summary>
        ///  <returns>評論數據訪問層對象</returns>
        #VALUE!
        public  static  ICommentDAL  CreateCommentDAL()
        {
            return  (ICommentDAL)DependencyInjector.GetDALObject("CommentDAL");
        }
    }
}

BLLFactory.cs
BLLFactory

using  System;
using  NGuestBook.IBLL;
#VALUE!
namespace  NGuestBook.Factory
{
    /**////  <summary>
    ///  業務邏輯層工廠,用於獲取相應的業務邏輯層對象
    ///  使用 Abstract  Factory 設計模式+Facace 設計模式+反射機制+緩存機制設計
    ///  </summary>
    0  public  sealed  class  BLLFactory
    {
        /**////  <summary>
        ///  獲取管理員業務邏輯層對象
        ///  </summary>
        ///  <returns>管理員業務邏輯層對象</returns>
        public  static  IAdminBLL  CreateAdminBLL()
        {
            return  (IAdminBLL)DependencyInjector.GetBLLObject("AdminBLL");
            #VALUE!
        }
        #VALUE!
        /**////  <summary>
        ///  獲取留言業務邏輯層對象
        ///  </summary>
        ///  <returns>留言業務邏輯層對象</returns>
        public  static  IMessageBLL  CreateMessageBLL()
        {
            return  (IMessageBLL)DependencyInjector.GetBLLObject("MessageBLL");
        }
        #VALUE!
        /**////  <summary>
        ///  獲取評論業務邏輯層對象
        ///  </summary>
        ///  <returns>評論業務邏輯層對象</returns>
        public  static  ICommentBLL  CreateCommentBLL()
        {
            return  (ICommentBLL)DependencyInjector.GetBLLObject("CommentBLL");
        }
    }
}
}

數據訪問實現方法一:ACCESS+SQL
通過上面篇文章的介紹, 整個系統的框架算是基本搭建完了, 下面, 咱們要具體實現各個層
次。關於數據訪問層的實現,我準備討論三種實現方式,這一篇文章討論第一種:Access
+動態生成 SQL。
顧名思義,這種現將使用 Access 做爲後臺數據庫,而操做方式也是最基本的使用 S
QL 命令。
在具體編寫現代碼以前,咱們須要作一些準備工做:
第一步,咱們要將 Access 數據庫搭建完成,具體作法以下。
45
在 Web 工程下新建一個文件夾, 命名爲 AccessData, 並在其中新建一個 mdb 文件(即
Access 數據庫文件),按照前面介紹過的數據庫設計構架,將數據表及表間關係建好,這
裏再也不贅述。
第二步,咱們要進行一些配置。
打開 Web 工程下的 Web.config 文件,在其中的 appSettings 節點下,添加以下鍵值:

顯示行號 複製代碼 這是一段程序代碼。
  1. <add  key="AccessConnectionString"  value="Provider=Microsoft.Jet.OLEDB.4.0;
  2. Data  Source={DBPath}"/> 
  3. <add  key="AccessPath"  value="~/AccessData/AccessDatabase.mdb"/>

第一條爲 Access 的鏈接字符串,第二條爲 Access 數據庫文件的路徑,其中「~」表示網
站根目錄。
第三步,新建一個工程。
咱們要新建一個工程 AccessDAL,用來存放 Access 數據訪問層的代碼。
準備工做作完了,如今來現具體的代碼。
1.編寫數據訪問助手類
由於不少數據訪問操做流程很類似, 因此,這裏將一些可複用的代碼抽取出來, 編寫成
助手類,以此減小代碼量,提升代碼複用性。
這個助手類放在 AccessDAL 下, 叫 AccessDALHelper,主要負責 Access 數據庫的訪
問。它包括三個方法:
GetConnectionString:從配置文件中讀取配置項,組合成鏈接字符串。
ExecuteSQLNonQuery:執行指定 SQL 語句,不返回任何值,通常用於 Insert,Delet
e,Update 命令。
ExecuteSQLDataReader:執行 SQL 語句返回查詢結果,通常用於 Select 命令。
46
具體代碼以下:
AccessDALHelper.cs:
AccessDALHelper

using  System;
using  NGuestBook.IBLL;
#VALUE!
namespace  NGuestBook.Factory
{
    /**////  <summary>
    ///  業務邏輯層工廠,用於獲取相應的業務邏輯層對象
    ///  使用 Abstract  Factory 設計模式+Facace 設計模式+反射機制+緩存機制設計
    ///  </summary>
    public  sealed  class  BLLFactory
    {
        /**////  <summary>
        ///  獲取管理員業務邏輯層對象
        ///  </summary>
        ///  <returns>管理員業務邏輯層對象</returns>
        public  static  IAdminBLL  CreateAdminBLL()
        {
            return  (IAdminBLL)DependencyInjector.GetBLLObject("AdminBLL");
 
        }
 
        /**////  <summary>
        ///  獲取留言業務邏輯層對象
        ///  </summary>
        ///  <returns>留言業務邏輯層對象</returns>
        public  static  IMessageBLL  CreateMessageBLL()
        {
            return  (IMessageBLL)DependencyInjector.GetBLLObject("MessageBLL");
        }
 
        /**////  <summary>
        ///  獲取評論業務邏輯層對象
        ///  </summary>
        ///  <returns>評論業務邏輯層對象</returns>
        public  static  ICommentBLL  CreateCommentBLL()
        {
            return  (ICommentBLL)DependencyInjector.GetBLLObject("CommentBLL");
        }
    }
}
}

2.現具體的數據訪問操做類
由於前面已經定義了數據訪問層接口,因此實現數據訪問操做類就是很機械的工做了。
下面僅以 Admin 的數據訪問操做類爲例:
AdminDAL:
AdminDAL

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Data;
using  System.Data.OleDb;
using  NGuestBook.IDAL;
using  NGuestBook.Entity;
 
 
amespace  NGuestBook.AccessDAL
{
    public  class  AdminDAL  :  IAdminDAL
    {
        /**////  <summary>
        ///  插入管理員
        ///  </summary>
        ///  <param  name="admin">管理員體類</param>
        ///  <returns>是否成功</returns>
        public  bool  Insert(AdminInfo  admin)
        {
            string  SQLCommand  =  "insert  into  [TAdmin]([Name],[Password])  values(@name,@password)";
            #VALUE!
            OleDbParameter[]  parameters  ={
                new  OleDbParameter("name",admin.Name),
                new  OleDbParameter("password",admin.Password)
            };
 
            try
            {
                AccessDALHelper.ExecuteSQLNonQuery(SQLCommand,  parameters);
                return  true;
            }
            catch
            {
                return  false;
            }
 
        }
 
        /**////  <summary>
        ///  刪除管理員
        ///  </summary>
        ///  <param  name="id">欲刪除的管理員的 ID</param>
        ///  <returns>是否成功</returns>
        public  bool  Delete(int  id)
        {
            string  SQLCommand  =  "delete  from  [TAdmin]  where  [ID]=@id";
            OleDbParameter[]  parameters  ={
                new  OleDbParameter("id",id)
            };
 
            try
            {
                AccessDALHelper.ExecuteSQLNonQuery(SQLCommand,  parameters);
                return  true;
            }
            catch
            {
                return  false;
            }
        }
 
        /**////  <summary>
        ///  更新管理員信息
        ///  </summary>
 
        ///  <param  name="admin">管理員體類</param>
        ///  <returns>是否成功</returns>
        public  bool  Update(AdminInfo  admin)
        {
            string  SQLCommand  =  "update  [TAdmin]  set  [Name]=@name,[Password]=@password  where  [ID]=@id";
            #VALUE!
            OleDbParameter[]  parameters  ={
                new  OleDbParameter("id",admin.ID),
                new  OleDbParameter("name",admin.Name),
                new  OleDbParameter("password",admin.Password)
            };
 
            try
            {
                AccessDALHelper.ExecuteSQLNonQuery(SQLCommand,  parameters);
                return  true;
            }
            catch
            {
                return  false;
            }
        }
 
        /**////  <summary>
 
        ///  </summary>
        ///  <param  name="id">管理員 ID</param>
        ///  <returns>管理員體類</returns>
 
        public  AdminInfo  GetByID(int  id)
        {
            string  SQLCommand  =  "select  *  from  [TAdmin]  where  [ID]=@id";
            OleDbParameter[]  parameters  ={
                new  OleDbParameter("id",id)
            };
 
            try
            {
                OleDbDataReader  dataReader  =  AccessDALHelper.ExecuteSQLDataReader(SQLCommand,  parameters);
                #VALUE!
                if  (!dataReader.HasRows)
                {
                    throw  new  Exception();
                }
 
                AdminInfo  admin  =  new  AdminInfo();
                dataReader.Read();
                admin.ID=(int)dataReader["ID"];
                admin.Name=(string)dataReader["Name"];
                admin.Password=(string)dataReader["Password"];
 
                return  admin;
            }
            catch
            {
                return  null;
            }
 
        }
 
        /**////  <summary>
        ///  按用戶名及密碼取得管理員信息
        ///  </summary>
        ///  <param  name="name">用戶名</param>
        ///  <param  name="password">密碼</param>
        ///  <returns>管理員體類,不存在時返回 null</returns>
        public  AdminInfo  GetByNameAndPassword(string  name,  string  password)
        {
            string  SQLCommand  =  "select  *  from  [TAdmin]  where  [Name]=@name
                [Password]=@password";
                OleDbParameter[]  parameters  ={
                new  OleDbParameter("name",name),
                new  OleDbParameter("password",password),
            };
 
            try
            {
                OleDbDataReader  dataReader  =  AccessDALHelper.ExecuteSQLDataReader(SQLCommand,  parameters);
                #VALUE!
                if  (!dataReader.HasRows)
                {
                    throw  new  Exception();
                }
 
                AdminInfo  admin  =  new  AdminInfo();
                dataReader.Read();
 
                admin.ID  =  (int)dataReader["ID"];
                admin.Name  =  (string)dataReader["Name"];
                admin.Password  =  (string)dataReader["Password"];
 
                return  admin;
            }
            catch
            {
                return  null;
            }
        }
 
        /**////  <summary>
        ///  按管理員名取得管理員信息
        ///  </summary>
        ///  <param  name="name">管理員名</param>
        ///  <returns>管理員體類</returns>
        public  AdminInfo  GetByName(string  name)
        {
            string  SQLCommand  =  "select  *  from  [TAdmin]  where  [Name]=@name";
            OleDbParameter[]  parameters  ={
                new  OleDbParameter("name",name),
            };
 
            try
            {
                OleDbDataReader  dataReader  =  AccessDALHelper.ExecuteSQLDataReader(SQLCommand,  parameters);
                #VALUE!
 
                if  (!dataReader.HasRows)
                {
                    throw  new  Exception();
                }
 
                AdminInfo  admin  =  new  AdminInfo();
                dataReader.Read();
                admin.ID  =  (int)dataReader["ID"];
                admin.Name  =  (string)dataReader["Name"];
                admin.Password  =  (string)dataReader["Password"];
 
                return  admin;
            }
            catch
            {
                return  null;
            }
        }
 
        /**////  <summary>
        ///  取得所有管理員信息
        ///  </summary>
        ///  <returns>管理員體類集合</returns>
        public  IList<AdminInfo>  GetAll()
        {
            string  SQLCommand  =  "select  *  from  [TAdmin]";
            try
            {
 
                OleDbDataReader  dataReader  =  AccessDALHelper.ExecuteSQLDataReader(SQLCommand,  null);
                #VALUE!
                if  (!dataReader.HasRows)
                {
                    throw  new  Exception();
                }
 
                IList<AdminInfo>  adminCollection  =  new  List<AdminInfo>();
                int  i  =  0;
                while  (dataReader.Read())
                {
                    AdminInfo  admin  =  new  AdminInfo();
                    admin.ID  =  (int)dataReader["ID"];
                    admin.Name  =  (string)dataReader["Name"];
                    admin.Password  =  (string)dataReader["Password"];
 
                    adminCollection.Add(admin);
                    i++;
                }
 
                return  adminCollection;
            }
            catch
            {
                return  null;
            }
        }
 
    }
}
相關文章
相關標籤/搜索