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;
            }
        }
 
    }
}
相关文章
相关标签/搜索