1、實體類是現實css
實體在計算機中的表示。 它貫穿於整個架構, 負擔着在各層次及模塊間傳遞數
據的職責。通常來講,實體類能夠分爲「貧血實體類」和「充血實體類」,前者僅僅保存實體的
屬性,然後者還包含一些體間的關係與邏輯。咱們在這個 Demo 中用的實體類將是「貧血
體類」。
大多狀況下, 實體類和數據庫中的表 (這裏指體表, 不包括表示多對多對應的關係表)
是一一對應的, 但這並非一個限制,在複雜的數據庫設計中, 有可能出現一個實體類對應
多個表,或者交叉對應的狀況。在本文的 Demo 中,實體類和表是一一對應的,而且體
類中的屬性和表中的字段也是對應的。
在看實體類的代碼前,先看一下系統的工程結構。數據庫
如上圖所示,在初始階段,整個系統包括 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 設計模式,這裏結合具體實例簡單介紹一下。
上圖以數據訪問層爲例, 展現了 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 節點下,添加以下鍵值:
<add key="AccessConnectionString" value="Provider=Microsoft.Jet.OLEDB.4.0;
Data Source={DBPath}"/>
<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;
}
}
}
}