• NHibernate框架与BLL+DAL+Model+Controller+UI 多层架构十分相似--『Spring.NET+NHibernate+泛型』概述、知识准备及介绍(一)


     

    原文://http://blog.csdn.net/wb09100310/article/details/47271555

    1. 概述

          搭建了Spring.NET+NHibernate的一个数据查询系统。之前没用过这两个框架,也算是先学现买,在做完设计之 后花了一周搭建成功了。其中,还加上了我的一些改进思想,把DAO和BLL之中相似且常用的增删改查通过泛型T抽象到了DAO和BLL的父类中,其DAO 和BLL子类只需继承父类就拥有了这些方法。和之前的一个数据库表(视图)对应一个实体,一个实体对应一个DAO和一个BLL,而每一个DAO和BLL都 是相似的增删改查相比,减少了大量代码量。现在就对这些知识做一个总结,方便自己学习,同时把自己的所思所悟分享给大家,不足知足望大家指点迷津!

    2. 知识准备

            温馨提示,学习本系列知识,须至少具备如下知识。否则请移步,熟悉下列知识之后再回来学习:

            1.C#基础扎实,熟悉泛型、反射、linq(最好有所了解)、ADO.NET

            2.熟悉XML

            3.对控制反转(IOC)、依赖注入(DI),Spring.net等理论知识有所了解,可以参考如下博文:

    Spring.NET学习笔记:http://www.cnblogs.com/GoodHelper/archive/2009/11/20/SpringNet_Index.html

              SPRING.NET 1.3.2学习:http://blog.csdn.net/lee576/article/category/1353489/2

            4.对Nhibernate理论知识有所了解,参考资料

             NHibernate之旅:http://www.cnblogs.com/lyj/archive/2008/10/10/1308267.html

             Nhibernate从入门到精通:http://www.cnblogs.com/GoodHelper/archive/2011/02/14/nhiberante_01.html

            5.Spring.NET+Nhibernate参考资料:

             Spring.NET学习笔记18——整合NHibernate(基础篇)Level 300:http://www.cnblogs.com/GoodHelper/archive/2009/11/18/SpringNet_NHibernate.html

             Spring.NET 1.3.2 集成 NHibernate 3.2:http://www.cnblogs.com/haogj/archive/2012/07/28/nhibernate.html

    3.项目介绍

             本项目后端采用Spring.NET2.0+Nhibernate4.0的经典三层架构,web端采用的是ASP.NET(本来打算用MVC,考虑到项目组成员对web开发不熟),项目结构如下:

              

              说明:

              Model:实体层,在NHibernate中也叫持久层

              IDAO:数据库访问层接口

              NHibernateDAO:实现IDAO,NHibernate框架实现数据库访问层

              IBLL:业务逻辑接口层

              BLL:业务逻辑层

              Common:工具类库层

              WebUI:表现层,ASP.NET,采用了BootStrap框架。这一层不是本次学习的重点

    4.Spring.NET简单介绍

              Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序。它提供了很多方面的功能,比如依赖注入、面向方面编程(AOP)、数据访问抽象及ASP.NET扩展等等。Spring.NETJava版的Spring框架为基础,将Spring.Java的核心概念与思想移植到了.NET平台上。

             Spring.NETIOC容器所解决的,正是如何在企业应用中将类、对象和服务组合成应用程序的问题。IOC容器通过很正统(按:formalized,言下之意是这些方式都是已经定型了的、经过了业界多年考验的)的方式将分散的组件组合成完整的应用程序。Spring.NET框架所采用的,都是被业界无数应用程序考验多年的、已经被定型为设计模式的最佳编程方式,实际上,这些模式已经成为我们架构和开发时的法典,而通过Spring.NET,我们可以直接将它们整合到自己的应用程序中。目前已有很多组织和机构用Spring框架开发出了强壮的、维护性好的应用程序,这确实是一件非常好的事情。

             

             Spring.NET框架包含了许多功能方面,它们都进入如下图所示的模块组织。下图显示了Spring.NET各核心模块:

    Spring.Core作为整个框架的基础, ,实现了依赖注入的功能。

    Spring.AOP为业务对象提供面向方面编程(AOP)的支持。

    Spring.Data定义了一个抽象的数据访问层,可以跨越各种数据访问技术(从ADO.NET到各种ORM)进行数据访问。

    Spring.Data.NHibernate使用此模块集成到Spring的声明式事务管理功能NHibernate的能容易地操作ADO.NETNHibernate的混合在同一事务。


     5.NHibernate框架简单介绍

             NHibernate是一个面向.NET环境的对象/关系数据库映射工具。对象关系映射(O/R MappingObject Relational Mapping)表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去。

             NHibernate不仅仅管理.NET类到数据库表的映射(包括.NET数据类型到SQL数据类型的映射),还提供数据查询和获取数据的方法,大幅度减少我们开发时人工使用SQLADO.NET处理数据的时间。NHibernate的目标是对于开发者通常的数据持久化相关的编程任务,解放其中的95%。并请记住NHibernate作为数据库访问层,是与你的程序紧密集成的。不过我个人觉得:NHibernate的性能明显没有纯sql性能好,不过在不太多考虑性能的情况下,它是比较好的选择!

    按照搭建项目的顺序来比较好描述一些,我一般先搭建实体层,本节内容纯属于NHibernate范畴。先上图和代码,然后对着图和代码逐一讲解,以角色表为例:

    『Spring.NET+NHibernate+泛型』框架搭建之Model(二)


      T_Role表:


      数据库表设计很简单,ID为主键,并且是自增长的,其他字段还包括角色名称(Name)、描述(Content)、排序(Sort)、状态(Status)、Del(是否删除)。这里就不对T_Role表赘述了。


       T_Role类:

    [csharp] view plain copy
    1. using System;  
    2.   
    3. //Nhibernate Code Generation Template 1.0  
    4. //author:MythXin  
    5. //blog:www.cnblogs.com/MythXin  
    6. //Entity Code Generation Template  
    7. namespace Model{  
    8.         //T_Role  
    9.         public class T_Role  
    10.     {  
    11.       
    12.         /// <summary>  
    13.         /// ID  
    14.         /// </summary>  
    15.         public virtual int ID  
    16.         {  
    17.             get;   
    18.             set;   
    19.         }          
    20.         /// <summary>  
    21.         /// Name  
    22.         /// </summary>  
    23.         public virtual string Name  
    24.         {  
    25.             get;   
    26.             set;   
    27.         }          
    28.         /// <summary>  
    29.         /// Content  
    30.         /// </summary>  
    31.         public virtual string Content  
    32.         {  
    33.             get;   
    34.             set;   
    35.         }          
    36.         /// <summary>  
    37.         /// Order  
    38.         /// </summary>  
    39.         public virtual int? Sort  
    40.         {  
    41.             get;   
    42.             set;   
    43.         }          
    44.         /// <summary>  
    45.         /// 1 启用(默认)  
    46.         ///0 禁用  
    47.         /// </summary>  
    48.         public virtual string Status  
    49.         {  
    50.             get;   
    51.             set;   
    52.         }          
    53.         /// <summary>  
    54.         /// 1 正常(默认)  
    55.       ///0 删除  
    56.         /// </summary>  
    57.         public virtual string Del  
    58.         {  
    59.             get;   
    60.             set;   
    61.         }          
    62.              
    63.     }  
    64. }  


      T_Role类必须与T_Role表的字段一一对应,名字可以不一样,但是字段属性数量和类型必须是一一对应的,此外,每个字段属性都必须为virtual的。


    T_Role表与T_Role的映射文件:

    1. <?xml version="1.0" encoding="utf-8" ?>  
    2. <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Model" >  
    3.   <class name="Model.T_Role, Model" table="T_Role">  
    4.     <id name="ID" column="ID" type="int" unsaved-value="0">  
    5.       <generator class="native"/>  
    6.     </id>  
    7.     <property name="Name" type="string" column="Name" />  
    8.     <property name="Content" type="string" column="Content" />  
    9.     <property name="Sort" type="int" column="Sort" />  
    10.     <property name="Status" type="string" column="Status" />  
    11.     <property name="Del" type="string" column="Del" />  
    12.   </class>  
    13. </hibernate-mapping>  


      顾名思义,T_Role的映射文件是映射T_Role类和T_Role表的。注意以下几点:

      (1) 必须按照上述格式书写,其中:

        a. hibernate-mapping固定上述格式,assembly为文件所在的命名空间;

        b. class标签中的name为“T_Role的命名空间.T_Role,T_Role的命名空间”,table为T_Role表的表名;

        c. id标签为主键,必须有主键,unsaved-value="0"意思是默认值是0,<generator class="native"/>表示按照数据库定义的方式处理主键,如我定义了自增长;

        d. id或property标签中的name为T_Role类中字段名称,而column必须为与之对应的T_Role表的字段名称,且数据类型相同;

      (2) 文件必须以.hbm.xml后缀结尾,如:T_Role.hbm.xml;

      (3) 必须右键点击文件-属性,将生成操作选为“嵌入的资源


      说明:T_Role类文 件(.cs文件)和T_Role映射文件(.hbm.xml)按理说可以分别放到不同的文件夹,但是这样放,运行的时候却提示找不到,最后无奈只能放一起 了。要是哪位大神解决了此问题麻烦留言告知,谢谢。另外,视图和表的方式完全一样的,映射的时候指定映射的视图就行了。

      最后,实体类和映射文件都是可以通过代码生成器生成的,建议不要自己去写,容易出错,还找不出错在哪里,用代码生成器生成之后不对的修改下就可以了。我使 用的动软代码生成器,代码生成器连接上数据库后,右键对应的数据库选择“模板代码批量生成”,选定要生成的表、模板就可以了,操作很简单,就不详述了,不 清楚的留言,或加入博客签名里的QQ群交流。


    贴上Model的目录图,并不需要任何多余的引用:


    『Spring.NET+NHibernate+泛型』框架搭建之DAO(三)★

      本节内容介绍Nhibernate所封装的数据库访问层。不过我加入了泛型进行封装。大概思路:首先,我们有一个接口层,还有一个对应的实现层;在接口层 中我们先定义一个父接口,父接口中定义每一个接口都可能会用到的方法,然后其他接口继承此父接口即可。如果子接口需要使用特殊的方法,可以单独定义在子接 口中;在接口实现层中也是类似的,定义一个父类,里面写好实现了接口层父接口的方法,其他实现层同样继承父接口和实现层父类,接口层中定义的特殊方法也在 对应的实现类中进行实现。这样做可以有效的把相似的重复代码(重复的增删改查)尽可能的减少,并且这样设计比较灵活,重复的写一次就行了,特殊的单独写, 维护起来也比较方便。这样描述可能不是很明白,下面详细介绍实现步骤。


    一、数据库访问接口层IDAO

      1. 在解决方案上右键新建一个类库,命名为IDAO,用来存放Nhibernae数据库访问接口层代码,并添加引用上一节所讲的实体层Model;

      2. 在类库中添加一个父接口,命名为IDAO,并定义常用的方法,代码如下:

    [csharp] view plain copy
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5.   
    6. namespace IDAO  
    7. {  
    8.     public interface IDAO<T>  
    9.     {  
    10.         /// <summary>  
    11.         /// 添加实体  
    12.         /// </summary>  
    13.         /// <param name="entity"></param>  
    14.         int Add(T entity);  
    15.   
    16.         /// <summary>  
    17.         /// 修改实体  
    18.         /// </summary>  
    19.         /// <param name="entity"></param>  
    20.         void Update(T entity);  
    21.   
    22.         /// <summary>  
    23.         /// 保存或修改实体  
    24.         /// </summary>  
    25.         /// <param name="customer"></param>  
    26.         void SaveOrUpdate(IList<T> list);  
    27.   
    28.         /// <summary>  
    29.         /// 删除实体  
    30.         /// </summary>  
    31.         /// <param name="entity"></param>  
    32.         void Delete(T entity);  
    33.   
    34.         /// <summary>  
    35.         /// 按条件删除  
    36.         /// </summary>  
    37.         /// <param name="sqlWhere">删除条件</param>  
    38.         void Delete(string sqlWhere);  
    39.   
    40.         /// <summary>  
    41.         /// 根据ID得到实体  
    42.         /// </summary>  
    43.         /// <param name="id"></param>  
    44.         /// <returns></returns>  
    45.         T Get(int id);  
    46.   
    47.         /// <summary>  
    48.         /// 根据ID得到实体  
    49.         /// </summary>  
    50.         /// <param name="id"></param>  
    51.         /// <returns></returns>  
    52.        T Load(int id);  
    53.   
    54.         /// <summary>  
    55.         /// 得到所有实体  
    56.         /// </summary>  
    57.         /// <returns></returns>  
    58.        IList<T> LoadAll();  
    59.   
    60.        /// <summary>  
    61.        /// 按条件排序得到前N条记录  
    62.        /// </summary>  
    63.        /// <param name="top">获取条数</param>  
    64.        /// <param name="field">排序字段</param>  
    65.        /// <param order="field">排序方式,升序asc,降序desc</param>  
    66.        /// <returns></returns>  
    67.        IList<T> QueryTop(int top, string field, string order);  
    68.   
    69.         /// <summary>  
    70.         /// 根据条件得到实体  
    71.         /// </summary>  
    72.         /// <param name="sqlWhere">查询条件</param>  
    73.         /// <returns></returns>  
    74.         IList<T> Where(string sqlWhere);  
    75.   
    76.         /// <summary>  
    77.         /// 得到统计数量  
    78.         /// </summary>  
    79.         /// <param name="strWhere">查询条件</param>  
    80.         /// <returns></returns>  
    81.         int GetRecordCount(string strWhere);  
    82.   
    83.         /// <summary>  
    84.         /// 分页获取数据列表  
    85.         /// </summary>  
    86.         /// <param name="PageSize">每页获取数据条数</param>  
    87.         /// <param name="PageIndex">当前页是第几页</param>  
    88.         /// <param name="strWhere">查询条件</param>  
    89.         /// <returns></returns>  
    90.         IList<T> GetPageList(int PageSize, int PageIndex, string strWhere);  
    91.   
    92.         /// <summary>  
    93.         /// 根据数据字典父编码和编码获取名称  
    94.         /// </summary>  
    95.         /// <param name="parentNumber">父编码</param>  
    96.         /// <param name="number">编码</param>  
    97.         /// <returns></returns>  
    98.         string GetName(string parentNumber, string number);  
    99.   
    100.         /// <summary>  
    101.         /// 获取该父编码下最大编码  
    102.         /// </summary>  
    103.         /// <param name="parentNumber">父编码</param>  
    104.         /// <returns></returns>  
    105.         int GetMaxNumber(string parentNumber);  
    106.     }  
    107. }  

      3.定义好了父接口,下面定义子接口,还是以IT_RoleDAO为例,代码如下:

    [csharp] view plain copy
    1. using System;  
    2. using Model;  
    3.   
    4. namespace IDAO  
    5. {  
    6.     public interface IT_RoleDAO : IDAO<T_Role>  
    7.     {  
    8.     }  
    9. }  


      这样,IT_RoleDAO就拥有了IDAO定义了的方法,如果IT_RoleDAO有特殊方法,直接添加在IT_RoleDAO里面即可,以IT_AreaDAO为例,代码如下:

    [csharp] view plain copy
    1. using System;  
    2. using Model;  
    3.   
    4. namespace IDAO  
    5. {  
    6.     public interface IT_AreaDAO : IDAO<T_Area>  
    7.     {  
    8.         /// <summary>  
    9.         /// 获取  
    10.         /// </summary>  
    11.         /// <param name="parentNumber"></param>  
    12.         /// <returns></returns>  
    13.         int GenerateAreaNumber(string parentNumber);  
    14.     }  
    15. }  


      最后,我们看一下IDAO层的文件目录:


    二、NHibernate数据库访问实现层NHibernateDAO(核心)

      1. 在解决方案上右键新建一个类库,命名为NHibernateDAO,用来存放Nhibernae数据库访问实现层代码,并添加引用上一节所讲的实体层Model和接口层IDAO;

      2. 右键点击引用,选择“管理NuGet程序包”,选择“联机”,搜索 “Spring.NET”,在搜索结果中选择“Spring.Net NHibernate 4 support”安装。该安装包括了一个NHibernate,但是还不够,同样的方法搜索NHibernate,并安装,添加Nhibernate就不上图了,添加Spring.NET的界面图如下:




      3.添加数据库访问层父类NHibernateDAO,NHibernateDAO类中的SessionFactory属性的 GetCurrentSession方法可以实例化ISession,实例化ISession后的对象可以调用NHibernate下的数据库操作方法, 具体他们之间怎么实例化,先上代码,后面再来解释。


      NHibernateDAO代码如下,继承INHibernateSessionFactory和实现IDAO父接口:

    [csharp] view plain copy
    1. using System;  
    2. using System.Collections;  
    3. using System.Collections.Generic;  
    4. using System.Linq;  
    5. using Model;  
    6. using IDAO;  
    7. using NHibernate;  
    8. using NHibernate.Criterion;  
    9. using NHibernate.Linq;  
    10. using Spring.Data.NHibernate.Support;  
    11. using NHibernate.Cfg;  
    12. using System.Text;  
    13.   
    14. namespace NHibernateDAO  
    15. {  
    16.     [Spring.Stereotype.Repository]  
    17.     public class NHibernateDAO<T> : IDAO<T>  
    18.     {  
    19.         public ISessionFactory SessionFactory { get; set; }  
    20.         /// <summary>  
    21.         /// 获取Session  
    22.         /// </summary>  
    23.         public ISession Session  
    24.         {  
    25.             get  
    26.             {  
    27.                 return SessionFactory.GetCurrentSession();  
    28.             }  
    29.         }  
    30.   
    31.         /// <summary>  
    32.         /// 当前实体对应的表名  
    33.         /// </summary>  
    34.         public string TableName  
    35.         {  
    36.             get { return typeof(T).ToString().Substring(typeof(T).ToString().LastIndexOf('.') + 1); }  
    37.         }  
    38.         /// <summary>  
    39.         /// 添加实体  
    40.         /// </summary>  
    41.         /// <param name="entity"></param>  
    42.         public int Add(T entity)  
    43.         {  
    44.                 using (ITransaction transaction = Session.BeginTransaction())  
    45.                 {  
    46.                     try  
    47.                     {  
    48.                         int id = (int)Session.Save(entity);  
    49.                         Session.Flush();  
    50.                         transaction.Commit();  
    51.                         return id;  
    52.                     }  
    53.                     catch (HibernateException)  
    54.                     {  
    55.                         transaction.Rollback();  
    56.                         throw;  
    57.                     }  
    58.             }  
    59.         }  
    60.   
    61.         /// <summary>  
    62.         /// 修改实体  
    63.         /// </summary>  
    64.         /// <param name="entity"></param>  
    65.         public void Update(T entity)  
    66.         {  
    67.                 using (ITransaction transaction = Session.BeginTransaction())  
    68.                 {  
    69.                     try  
    70.                     {  
    71.                         Session.Update(entity);  
    72.                         Session.Flush();  
    73.                         transaction.Commit();  
    74.                     }  
    75.                     catch (HibernateException)  
    76.                     {  
    77.                         transaction.Rollback();  
    78.                         throw;  
    79.                     }  
    80.             }  
    81.         }  
    82.         /// <summary>  
    83.         /// 保存或修改实体  
    84.         /// </summary>  
    85.         /// <param name="customer"></param>  
    86.         public void SaveOrUpdate(IList<T> list)  
    87.         {  
    88.                 using (ITransaction transaction = Session.BeginTransaction())  
    89.                 {  
    90.                     try  
    91.                     {  
    92.                         foreach (var entity in list)  
    93.                         {  
    94.                             Session.SaveOrUpdate(entity);  
    95.                         }  
    96.                         Session.Flush();  
    97.                         transaction.Commit();  
    98.                     }  
    99.                     catch (HibernateException)  
    100.                     {  
    101.                         transaction.Rollback();  
    102.                         throw;  
    103.                     }  
    104.             }  
    105.         }  
    106.   
    107.         /// <summary>  
    108.         /// 删除实体  
    109.         /// </summary>  
    110.         /// <param name="entity"></param>  
    111.         public void Delete(T entity)  
    112.         {  
    113.                 using (ITransaction transaction = Session.BeginTransaction())  
    114.                 {  
    115.                     try  
    116.                     {  
    117.                         Session.Delete(entity);  
    118.                         Session.Flush();  
    119.                         transaction.Commit();  
    120.                     }  
    121.                     catch (HibernateException)  
    122.                     {  
    123.                         transaction.Rollback();  
    124.                         throw;  
    125.                     }  
    126.                 }  
    127.         }  
    128.   
    129.         /// <summary>  
    130.         /// 按条件删除  
    131.         /// </summary>  
    132.         /// <param name="sqlWhere">删除条件</param>  
    133.         public void Delete(string sqlWhere)  
    134.         {  
    135.                 using (ITransaction transaction = Session.BeginTransaction())  
    136.                 {  
    137.                     try  
    138.                     {  
    139.                         Session.Delete(string.Format("from {0} Where {1}", TableName, sqlWhere));  
    140.                         Session.Flush();  
    141.                         transaction.Commit();  
    142.                     }  
    143.                     catch (HibernateException)  
    144.                     {  
    145.                         transaction.Rollback();  
    146.                         throw;  
    147.                     }  
    148.             }  
    149.         }  
    150.   
    151.         /// <summary>  
    152.         /// 根据ID得到实体  
    153.         /// </summary>  
    154.         /// <param name="id"></param>  
    155.         /// <returns></returns>  
    156.         public T Get(int id)  
    157.         {  
    158.             return Session.Get<T>(id);  
    159.         }  
    160.         /// <summary>  
    161.         /// 根据ID得到实体  
    162.         /// </summary>  
    163.         /// <param name="id"></param>  
    164.         /// <returns></returns>  
    165.         public T Load(int id)  
    166.         {  
    167.             return Session.Load<T>(id);  
    168.         }  
    169.         /// <summary>  
    170.         /// 得到所有实体  
    171.         /// </summary>  
    172.         /// <returns></returns>  
    173.         public IList<T> LoadAll()  
    174.         {  
    175.             return Session.Query<T>().ToList();  
    176.         }  
    177.   
    178.         /// <summary>  
    179.         /// 按条件排序得到前N条记录  
    180.         /// </summary>  
    181.         /// <param name="top">获取条数</param>  
    182.         /// <param name="field">排序字段</param>  
    183.         /// <param order="field">排序方式,升序asc,降序desc</param>  
    184.         /// <returns></returns>  
    185.         public IList<T> QueryTop(int top, string field, string order)  
    186.         {  
    187.             if (order == "asc")  
    188.             {  
    189.                 return Session.CreateCriteria(typeof(T)).SetMaxResults(top).AddOrder(Order.Asc(field)).List<T>();  
    190.             }  
    191.             else  
    192.             {  
    193.                 return Session.CreateCriteria(typeof(T)).SetMaxResults(top).AddOrder(Order.Desc(field)).List<T>();  
    194.             }  
    195.         }  
    196.   
    197.         /// <summary>  
    198.         /// 根据条件得到实体  
    199.         /// </summary>  
    200.         /// <param name="sqlWhere">查询条件</param>  
    201.         /// <returns></returns>  
    202.         public IList<T> Where(string sqlWhere)  
    203.         {  
    204.             StringBuilder strSql = new StringBuilder(string.Format("from {0} c", TableName));  
    205.             if (!string.IsNullOrEmpty(sqlWhere))  
    206.             {  
    207.                 strSql.Append(string.Format(" where {0}", sqlWhere));  
    208.             }  
    209.             return Session.CreateQuery(strSql.ToString()).List<T>();  
    210.         }  
    211.   
    212.         /// <summary>  
    213.         /// 得到统计数量  
    214.         /// </summary>  
    215.         /// <param name="strWhere">查询条件</param>  
    216.         /// <returns></returns>  
    217.         public int GetRecordCount(string sqlWhere)  
    218.         {  
    219.             StringBuilder strSql = new StringBuilder(string.Format("select count(1) from {0} c", TableName));  
    220.             if (!string.IsNullOrEmpty(sqlWhere))  
    221.             {  
    222.                 strSql.Append(string.Format(" where {0}", sqlWhere));  
    223.             }  
    224.             return (int)Session.CreateSQLQuery(strSql.ToString()).UniqueResult();  
    225.         }  
    226.   
    227.         /// <summary>  
    228.         /// 分页获取数据列表  
    229.         /// </summary>  
    230.         /// <param name="PageSize">每页获取数据条数</param>  
    231.         /// <param name="PageIndex">当前页是第几页</param>  
    232.         /// <param name="strWhere">查询条件</param>  
    233.         /// <returns></returns>  
    234.         public IList<T> GetPageList(int PageSize, int PageIndex, string sqlWhere)  
    235.         {  
    236.             StringBuilder strSql = new StringBuilder();  
    237.             strSql.Append(string.Format("select top {0} * from {1} where ID not in(select top  ", PageSize,  
    238.                 TableName));  
    239.             strSql.Append(PageSize * (PageIndex - 1));  
    240.             strSql.Append(string.Format(" ID from {0}", TableName));  
    241.             if (!string.IsNullOrEmpty(sqlWhere))  
    242.             {  
    243.                 strSql.Append(string.Format(" where {0} ) and {0}", sqlWhere));  
    244.             }  
    245.             else  
    246.             {  
    247.                 strSql.Append(")");  
    248.             }  
    249.             return Session.CreateSQLQuery(strSql.ToString()).AddEntity(typeof(T)).List<T>();  
    250.         }  
    251.   
    252.         /// <summary>  
    253.         /// 根据数据字典父编码和编码获取名称  
    254.         /// </summary>  
    255.         /// <param name="parentNumber">父编码</param>  
    256.         /// <param name="number">编码</param>  
    257.         /// <returns></returns>  
    258.         public string GetName(string parentNumber, string number)  
    259.         {  
    260.             string[] num = number.Split(',');  
    261.             List<string> list = new List<string>();  
    262.             list.AddRange(num);  
    263.             IQueryable<string> name = from q in Session.Query<T_Dictionary>()  
    264.                                       where q.ParentNumber == parentNumber && list.Contains(q.Number)   orderby q.Number  
    265.                                       select q.Name;  
    266.             string nameStr = "";  
    267.             foreach (string n in name)  
    268.             {  
    269.                 nameStr += n + ",";  
    270.             }  
    271.             return nameStr.Contains(",") ? nameStr.Substring(0, nameStr.Length - 1) : nameStr;  
    272.         }  
    273.   
    274.         /// <summary>  
    275.         /// 获取该父编码下最大编码  
    276.         /// </summary>  
    277.         /// <param name="parentNumber">父编码</param>  
    278.         /// <returns></returns>  
    279.         public int GetMaxNumber(string parentNumber)  
    280.         {  
    281.             string strSql =  
    282.                 string.Format(  
    283.                     "select case when MAX(cast(substring(Number,len(Number)-3,4) as int)) is null then 0 else MAX(cast(substring(Number,len(Number)-3,4) as int)) end  from {0} where ParentNumber='{1}'",  
    284.                     TableName, parentNumber);  
    285.             return ++Session.CreateQuery(strSql).List<int>()[0];  
    286.         }  
    287.   
    288.     }  
    289. }  


      4. 添加一个数据库访问层实现类,以T_RoleDAO为例:

    [csharp] view plain copy
    1. using System;  
    2. using System.Collections;  
    3. using IDAO;  
    4. using Model;  
    5.   
    6. namespace NHibernateDAO  
    7. {  
    8.     public class T_RoleDAO : NHibernateDAO<T_Role>, IT_RoleDAO  
    9.     {  
    10.           
    11.     }  
    12. }  


      同样滴,继承NHibernateDAO并实现IT_RoleDAO接口,他便拥有了他们定义好的方法。如果有特殊方法代码如下:

    [csharp] view plain copy
    1. using System;  
    2. using System.Collections;  
    3. using Model;  
    4. using IDAO;  
    5. using System.Text;  
    6. using System.Collections.Generic;  
    7.   
    8. using NHibernate;  
    9.   
    10. namespace NHibernateDAO  
    11. {  
    12.     public class T_AreaDAO : NHibernateDAO<T_Area>,IT_AreaDAO  
    13.     {  
    14.         public int GenerateAreaNumber(string parentNumber)  
    15.         {  
    16.             string sqlStr = string.Format(@"select case when MAX(cast(Number as int)) is null  then 0  
    17.                             else MAX(cast(Number as int)) end  
    18.                             from {0}  
    19.                             where ParentNumber={1}", TableName, parentNumber);  
    20.             return ++Session.CreateQuery(sqlStr).List<int>()[0];  
    21.         }  
    22.     }  
    23. }  

      5. 下面,就来解释一下他们都是怎么实例化的。这里就用到Spring.NET依赖注入的方式实现,先看配置文件。在NHibernateDAO类库下添加文 件夹Config,用来存放配置文件,然后添加一个命名为objects.xml的xml。这里必须定义每一个数据库访问层对象,不能说他们都继承 NHibernateDAO,只定义NHibernateDAO,这样的话会报错,因为后面BLL层要调用DAO层,他们之间是一一对应的,这里先简单提 一下,后面讲到就明白了。代码如下:

    1. <?xml version="1.0" encoding="utf-8" ?>  
    2. <objects xmlns="http://www.springframework.net">  
    3.     
    4.   <!--T_AreaDAO,管理T_Area的对象-->  
    5.   <object id="T_AreaDAO" type="NHibernateDAO.T_AreaDAO,NHibernateDAO">  
    6.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    7.   </object>  
    8.   
    9.   <!--T_AssessmentCoefficientDAO,管理T_AssessmentCoefficient的对象-->  
    10.   <object id="T_AssessmentCoefficientDAO" type="NHibernateDAO.T_AssessmentCoefficientDAO,NHibernateDAO">  
    11.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    12.   </object>  
    13.   
    14.   <!--T_AuthorityDAO,管理T_Authority的对象-->  
    15.   <object id="T_AuthorityDAO" type="NHibernateDAO.T_AuthorityDAO,NHibernateDAO">  
    16.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    17.   </object>  
    18.   
    19.   <!--T_ClientDAO,管理T_Client的对象-->  
    20.   <object id="T_ClientDAO" type="NHibernateDAO.T_ClientDAO,NHibernateDAO">  
    21.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    22.   </object>  
    23.   
    24.   <!--T_DictionaryDAO,管理T_Dictionary的对象-->  
    25.   <object id="T_DictionaryDAO" type="NHibernateDAO.T_DictionaryDAO,NHibernateDAO">  
    26.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    27.   </object>  
    28.   
    29.   <!--T_DrugDAO,管理T_Drug的对象-->  
    30.   <object id="T_DrugDAO" type="NHibernateDAO.T_DrugDAO,NHibernateDAO">  
    31.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    32.   </object>  
    33.   
    34.   <!--T_InvoicingCollectDetailDAO,管理T_InvoicingCollectDetail的对象-->  
    35.   <object id="T_InvoicingCollectDetailDAO" type="NHibernateDAO.T_InvoicingCollectDetailDAO,NHibernateDAO">  
    36.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    37.   </object>  
    38.   
    39.   <!--T_InvoicingDetailDAO,管理T_InvoicingDetail的对象-->  
    40.   <object id="T_InvoicingDetailDAO" type="NHibernateDAO.T_InvoicingDetailDAO,NHibernateDAO">  
    41.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    42.   </object>  
    43.   
    44.   <!--T_LogDAO,管理T_Log的对象-->  
    45.   <object id="T_LogDAO" type="NHibernateDAO.T_LogDAO,NHibernateDAO">  
    46.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    47.   </object>  
    48.   
    49.   <!--T_MenuDAO,管理T_Menu的对象-->  
    50.   <object id="T_MenuDAO" type="NHibernateDAO.T_MenuDAO,NHibernateDAO">  
    51.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    52.   </object>  
    53.   
    54.   <!--T_OpHistoryDAO,管理T_OpHistory的对象-->  
    55.   <object id="T_OpHistoryDAO" type="NHibernateDAO.T_OpHistoryDAO,NHibernateDAO">  
    56.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    57.   </object>  
    58.   
    59.   <!--T_RoleDAO,管理T_Role的对象-->  
    60.   <object id="T_RoleDAO" type="NHibernateDAO.T_RoleDAO,NHibernateDAO">  
    61.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    62.   </object>  
    63.   
    64.   <!--T_UserDAO,管理T_User的对象-->  
    65.   <object id="T_UserDAO" type="NHibernateDAO.T_UserDAO,NHibernateDAO">  
    66.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    67.   </object>  
    68.   
    69.   <!--V_InvoicingCollectDetailDAO,管理V_InvoicingCollectDetail的对象-->  
    70.   <object id="V_InvoicingCollectDetailDAO" type="NHibernateDAO.V_InvoicingCollectDetailDAO,NHibernateDAO">  
    71.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    72.   </object>  
    73.   
    74.   <!--V_InvoicingDetailDAO,管理V_InvoicingDetail的对象-->  
    75.   <object id="V_InvoicingDetailDAO" type="NHibernateDAO.V_InvoicingDetailDAO,NHibernateDAO">  
    76.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    77.   </object>  
    78.   
    79.   <!--V_TrackDAO,管理V_Track的对象-->  
    80.   <object id="V_TrackDAO" type="NHibernateDAO.V_TrackDAO,NHibernateDAO">  
    81.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    82.   </object>  
    83.   
    84.   <!--V_CoverageRateDAO,管理V_CoverageRate的对象-->  
    85.   <object id="V_CoverageRateDAO" type="NHibernateDAO.V_CoverageRateDAO,NHibernateDAO">  
    86.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    87.   </object>  
    88.     
    89.   <!--V_AssessDAO,管理V_Assess的对象-->  
    90.   <object id="V_AssessDAO" type="NHibernateDAO.V_AssessDAO,NHibernateDAO">  
    91.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    92.   </object>  
    93.     
    94.   <!--T_BuyDetailDAO,管理T_BuyDetail的对象-->  
    95.   <object id="T_BuyDetailDAO" type="NHibernateDAO.T_BuyDetailDAO,NHibernateDAO">  
    96.     <property name="SessionFactory" ref="NHibernateSessionFactory"/>  
    97.   </object>  
    98.     
    99. </objects>  


      格式如上述代码,先定义一个objects根节点,然后再objects中定义每一 个数据库访层,type指定“命名空间.类名,命名空间”,property指定属性,name必须与NHibernateDAO中的 SessionFactory相同,由于每一个数据库访问层都继承了NHibernateDAO,所有他们就拥有了NHibernateDAO的属性 SessionFactory,ref指定SessionFactory实例化的对象,NHibernateSessionFactory是 NHibernate框架封装的数据库访问类。所以,我们看到我们没有在代码中实实例化SessionFactory,只是定义了一个属性,而是通过Spring.NET的配置文件来把SessionFactory实例化的,这就是所谓的依赖注入,也交控制反转。


      6. 细心的撸友可以发现了,数据库操作的类和方法我们定义好了,但是数据访问的连接字符串还没有,下面就来配置数据库访问文件。同样在NHibernateDAO的Config中添加DataAccess.xml,代码如下:

    1. <?xml version="1.0" encoding="utf-8" ?>  
    2. <objects xmlns="http://www.springframework.net"  
    3.          xmlns:db="http://www.springframework.net/database"  
    4.          xmlns:tx="http://www.springframework.net/tx"  
    5.          >  
    6.   <!--描述-->  
    7.   <description>  
    8.     数据访问的配置信息  
    9.     包括:DbProvider  
    10.     NHibernate  
    11.   </description>  
    12.   
    13.   <!-- 通过主应用程序的上下文配置文件引用 -->  
    14.   <object type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core">  
    15.     <property name="ConfigSections" value="spring/databaseSettings"/>  
    16.   </object>  
    17.   
    18.   <!-- 数据库的配置 -->  
    19.   <db:provider id="DbProvider"  
    20.                    provider="SqlServer-2.0"  
    21.                    connectionString="Data Source=${db.server};Database=${db.database};User ID=${db.userid} ;PassWord=${db.password}"  
    22.                />  
    23.   
    24.   <!-- NHibernate 配置 -->  
    25.   
    26.   <!-- 可以通过 name 为其指定别名 name="SessionFactory" -->  
    27.   <object id="NHibernateSessionFactory"  
    28.           type="Spring.Data.NHibernate.LocalSessionFactoryObject,Spring.Data.NHibernate4"  
    29.           >  
    30.   
    31.     <!-- 关于数据库连接的配置,直接使用 DbProvider 中的设置,这样,不需要为 Hibernate 再提供连接串和驱动 -->  
    32.     <property name="DbProvider" ref="DbProvider"/>  
    33.   
    34.     <!-- 包含有映射文件的程序集,需要分析的hbm程序集名称 -->  
    35.     <property name="MappingAssemblies">  
    36.       <list>  
    37.         <value>Model</value>  
    38.       </list>  
    39.     </property>  
    40.   
    41.     <!-- 其他的参数 -->  
    42.     <property name="HibernateProperties">  
    43.       <dictionary>  
    44.         <!-- 方言 -->  
    45.         <entry key="dialect" value="NHibernate.Dialect.MsSql2008Dialect"/>  
    46.         <entry key="use_proxy_validator" value="false" />  
    47.         <entry key="show_sql" value="true"/>  
    48.   
    49.       </dictionary>  
    50.     </property>  
    51.   
    52.     <!-- 必须增加此项说明,与 Spring 的声明式事务集成 -->  
    53.     <property name="ExposeTransactionAwareSessionFactory" value="true" />  
    54.   
    55.   </object>  
    56.   
    57. </objects>  

      其中connectionString="Data Source=${db.server};Database=${db.database};User ID=${db.userid} ;PassWord=${db.password}中,我并没有明确指定他们访问地址、数据库等。这是一种类似定义一个变量的方式指定他们的访问地址、数 据库等信息的,具体变量的值是什么,会在后面web层的config配置文件中定义,按这个格式写就行,先不用纠结。这样也方便维护。


      最后,还是看一下NHibernateDAO层的目录结构:


    『Spring.NET+NHibernate+泛型』框架搭建之BLL(四)

    本节讲解业务逻辑层BLL。很简单和DAO层类似,通过泛型封装相似的功能到父类,其他子类继承父类即可,具体看下面操作。


    一、业务逻辑接口层IBLL

      1. 在解决方案上右键新建一个类库,命名为IBLL,用来存放业务逻辑接口层代码,并添加引用实体层Model,数据库访问接口层IDAO;

      2. 在类库中添加一个父接口,命名为IBLL,并定义常用的方法,代码如下:

    [csharp] view plain copy
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using IDAO;  
    6.   
    7. namespace IBLL  
    8. {  
    9.     public interface IBLL<T>  
    10.     {  
    11.         IDAO<T> Dao { get; set; }  
    12.   
    13.         /// <summary>  
    14.         /// 添加实体  
    15.         /// </summary>  
    16.         /// <param name="entity"></param>  
    17.         int Add(T entity);  
    18.   
    19.         /// <summary>  
    20.         /// 修改实体  
    21.         /// </summary>  
    22.         /// <param name="entity"></param>  
    23.         void Update(T entity);  
    24.   
    25.         /// <summary>  
    26.         /// 保存或修改实体  
    27.         /// </summary>  
    28.         /// <param name="customer"></param>  
    29.         void SaveOrUpdate(IList<T> list);  
    30.   
    31.         /// <summary>  
    32.         /// 删除实体  
    33.         /// </summary>  
    34.         /// <param name="entity"></param>  
    35.         void Delete(T entity);  
    36.   
    37.         /// <summary>  
    38.         /// 按条件删除  
    39.         /// </summary>  
    40.         /// <param name="sqlWhere">删除条件</param>  
    41.         void Delete(string sqlWhere);  
    42.   
    43.         /// <summary>  
    44.         /// 根据ID得到实体  
    45.         /// </summary>  
    46.         /// <param name="id"></param>  
    47.         /// <returns></returns>  
    48.         T Get(int id);  
    49.   
    50.         /// <summary>  
    51.         /// 根据ID得到实体  
    52.         /// </summary>  
    53.         /// <param name="id"></param>  
    54.         /// <returns></returns>  
    55.         T Load(int id);  
    56.   
    57.         /// <summary>  
    58.         /// 得到所有实体  
    59.         /// </summary>  
    60.         /// <returns></returns>  
    61.         IList<T> LoadAll();  
    62.   
    63.         /// <summary>  
    64.         /// 按条件排序得到前N条记录  
    65.         /// </summary>  
    66.         /// <param name="top">获取条数</param>  
    67.         /// <param name="field">排序字段</param>  
    68.         /// <param order="field">排序方式,升序asc,降序desc</param>  
    69.         /// <returns></returns>  
    70.         IList<T> QueryTop(int top, string field, string order = "asc");  
    71.   
    72.         /// <summary>  
    73.         /// 根据条件得到实体  
    74.         /// </summary>  
    75.         /// <param name="sqlWhere">查询条件</param>  
    76.         /// <returns></returns>  
    77.         IList<T> Where(string sqlWhere="");  
    78.   
    79.         /// <summary>  
    80.         /// 得到统计数量  
    81.         /// </summary>  
    82.         /// <param name="strWhere">查询条件</param>  
    83.         /// <returns></returns>  
    84.         int GetRecordCount(string strWhere = "");  
    85.   
    86.         /// <summary>  
    87.         /// 分页获取数据列表  
    88.         /// </summary>  
    89.         /// <param name="PageSize">每页获取数据条数</param>  
    90.         /// <param name="PageIndex">当前页是第几页</param>  
    91.         /// <param name="strWhere">查询条件</param>  
    92.         /// <returns></returns>  
    93.         IList<T> GetPageList(int PageSize, int PageIndex, string strWhere = "");  
    94.   
    95.         /// <summary>  
    96.         /// 根据数据字典父编码和编码获取名称  
    97.         /// </summary>  
    98.         /// <param name="parentNumber">父编码</param>  
    99.         /// <param name="number">编码</param>  
    100.         /// <returns></returns>  
    101.         string GetName(string parentNumber, string number);  
    102.   
    103.         /// <summary>  
    104.         /// 获取该父编码下最大编码  
    105.         /// </summary>  
    106.         /// <param name="parentNumber">父编码</param>  
    107.         /// <returns></returns>  
    108.         string GetMaxNumber(string parentNumber);  
    109.     }  
    110. }  


      3.定义好了父接口,下面定义子接口,还是以IT_RoleBLL为例,代码如下:

    [csharp] view plain copy
    1. using System;  
    2. using Model;  
    3.   
    4. namespace IBLL  
    5. {  
    6.     public interface IT_RoleBLL : IBLL<T_Role>  
    7.     {  
    8.     }  
    9. }  


      这样,IT_RoleBLL就拥有了IBLL定义了的方法,如果IT_RoleBLL有特殊方法,直接添加在IT_RoleBLL里面即可,以IT_AreaBLL为例,代码如下:


    [csharp] view plain copy
    1. using Model;  
    2. using System;  
    3. using System.Collections.Generic;  
    4. using System.Linq;  
    5. using System.Text;  
    6.   
    7. namespace IBLL  
    8. {  
    9.     public interface IT_AreaBLL : IBLL<T_Area>  
    10.     {  
    11.         int GenerateAreaNumber(string parentNumber);  
    12.     }  
    13. }  


      最后,我们看一下IBLL层的目录结构:



    二、业务逻辑实现层BLL


      1. 在解决方案上右键新建一个类库,命名为BLL,用来存放业务逻辑实现层代码,并添加引用IBLL接口层、实体层Model和数据库访问接口层IDAO;

      2. 在类库中添加一个父接口,命名为BLL,并定义常用的方法,代码如下:

    [csharp] view plain copy
    1. using IBLL;  
    2. using System;  
    3. using System.Collections.Generic;  
    4. using System.Linq;  
    5. using System.Text;  
    6. using Model;  
    7. using IDAO;  
    8.   
    9. namespace BLL  
    10. {  
    11.     public class BLL<T>:IBLL<T>  
    12.     {  
    13.         public IDAO<T> Dao { get; set; }  
    14.   
    15.         /// <summary>  
    16.         /// 添加实体  
    17.         /// </summary>  
    18.         /// <param name="entity"></param>  
    19.         public int Add(T entity)  
    20.         {  
    21.             return Dao.Add(entity);  
    22.         }  
    23.   
    24.         /// <summary>  
    25.         /// 修改实体  
    26.         /// </summary>  
    27.         /// <param name="entity"></param>  
    28.         public void Update(T entity)  
    29.         {  
    30.             Dao.Update(entity);  
    31.         }  
    32.         /// <summary>  
    33.         /// 保存或修改实体  
    34.         /// </summary>  
    35.         /// <param name="customer"></param>  
    36.         public void SaveOrUpdate(IList<T> list)  
    37.         {  
    38.             Dao.SaveOrUpdate(list);  
    39.         }  
    40.   
    41.         /// <summary>  
    42.         /// 删除实体  
    43.         /// </summary>  
    44.         /// <param name="entity"></param>  
    45.         public void Delete(T entity)  
    46.         {  
    47.             Dao.Delete(entity);  
    48.         }  
    49.   
    50.         /// <summary>  
    51.         /// 按条件删除  
    52.         /// </summary>  
    53.         /// <param name="sqlWhere">删除条件</param>  
    54.         public void Delete(string sqlWhere)  
    55.         {  
    56.             Dao.Delete(sqlWhere);  
    57.         }  
    58.   
    59.         /// <summary>  
    60.         /// 根据ID得到实体  
    61.         /// </summary>  
    62.         /// <param name="id"></param>  
    63.         /// <returns></returns>  
    64.         public T Get(int id)  
    65.         {  
    66.             return Dao.Get(id);  
    67.         }  
    68.         /// <summary>  
    69.         /// 根据ID得到实体  
    70.         /// </summary>  
    71.         /// <param name="id"></param>  
    72.         /// <returns></returns>  
    73.         public T Load(int id)  
    74.         {  
    75.             return Dao.Load(id);  
    76.         }  
    77.         /// <summary>  
    78.         /// 得到所有实体  
    79.         /// </summary>  
    80.         /// <returns></returns>  
    81.         public IList<T> LoadAll()  
    82.         {  
    83.             return Dao.LoadAll();  
    84.         }  
    85.   
    86.         /// <summary>  
    87.         /// 按条件排序得到前N条记录  
    88.         /// </summary>  
    89.         /// <param name="top">获取条数</param>  
    90.         /// <param name="field">排序字段</param>  
    91.         /// <param order="field">排序方式,升序asc,降序desc</param>  
    92.         /// <returns></returns>  
    93.         public IList<T> QueryTop(int top, string field, string order = "asc")  
    94.         {  
    95.             return Dao.QueryTop(top,field,order);  
    96.         }  
    97.   
    98.         /// <summary>  
    99.         /// 根据条件得到实体  
    100.         /// </summary>  
    101.         /// <param name="sqlWhere">查询条件</param>  
    102.         /// <returns></returns>  
    103.         public IList<T> Where(string sqlWhere = "")  
    104.         {  
    105.             return Dao.Where(sqlWhere);  
    106.         }  
    107.         /// <summary>  
    108.         /// 得到统计数量  
    109.         /// </summary>  
    110.         /// <param name="strWhere">查询条件</param>  
    111.         /// <returns></returns>  
    112.         public int GetRecordCount(string strWhere="")  
    113.         {  
    114.             return Dao.GetRecordCount(strWhere);  
    115.         }  
    116.   
    117.         /// <summary>  
    118.         /// 分页获取数据列表  
    119.         /// </summary>  
    120.         /// <param name="PageSize">每页获取数据条数</param>  
    121.         /// <param name="PageIndex">当前页是第几页</param>  
    122.         /// <param name="strWhere">查询条件</param>  
    123.         /// <returns></returns>  
    124.         public IList<T> GetPageList(int PageSize, int PageIndex, string strWhere="")  
    125.         {  
    126.             return Dao.GetPageList(PageSize,PageIndex,strWhere);  
    127.         }  
    128.   
    129.         /// <summary>  
    130.         /// 根据数据字典父编码和编码获取名称  
    131.         /// </summary>  
    132.         /// <param name="parentNumber">父编码</param>  
    133.         /// <param name="number">编码</param>  
    134.         /// <returns></returns>  
    135.         public string GetName(string parentNumber, string number)  
    136.         {  
    137.             return Dao.GetName(parentNumber, number);  
    138.         }  
    139.   
    140.         /// <summary>  
    141.         /// 获取该父编码下最大编码  
    142.         /// </summary>  
    143.         /// <param name="parentNumber">父编码</param>  
    144.         /// <returns></returns>  
    145.         public string GetMaxNumber(string parentNumber)  
    146.         {  
    147.             int max = Dao.GetMaxNumber(parentNumber);  
    148.             return parentNumber + max.ToString().PadLeft(4, '0');  
    149.         }  
    150.     }  
    151. }  


      3.定义好了父接口,下面定义子接口,以T_RoleBLL为例,代码如下:

    [csharp] view plain copy
    1. using System;  
    2. using IBLL;  
    3. using Model;  
    4.   
    5. namespace BLL  
    6. {  
    7.     public class T_RoleBLL : BLL<T_Role>,IT_RoleBLL  
    8.     {  
    9.     }  
    10. }  


    这样,T_RoleBLL就拥有了BLL定义了的方法,如果T_RoleBLL有特殊方法,直接添加在T_RoleBLL里面即可。不过要注意,对ITRoleDAO要单独实例化,原因:BLL中实例化的IDAO<T>对象仅仅是拥调用IDAO中定义的方法,并不拥有单独在子类定义的方法。以T_AreaBLL为例,代码如下:

    [csharp] view plain copy
    1. using IBLL;  
    2. using IDAO;  
    3. using Model;  
    4. using System;  
    5. using System.Collections.Generic;  
    6. using System.Linq;  
    7. using System.Text;  
    8.   
    9. namespace BLL  
    10. {  
    11.     public class T_AreaBLL : BLL<T_Area>,IT_AreaBLL  
    12.     {  
    13.         public IT_AreaDAO AreaDao { get; set; }  
    14.   
    15.         public int GenerateAreaNumber(string parentNumber)  
    16.         {  
    17.             return AreaDao.GenerateAreaNumber(parentNumber);  
    18.         }  
    19.     }  
    20. }  


      至于BLL中的Dao和T_AreaBLL中的AreaDao是如何被实例化的,我们在下一节再说!大家可以回忆一下DAO层中ISessionFactory对象SessionFactory是如何实例化的?这里用到了Spring.NET的依赖注入功能。最后,还是看一下BLL层的目录结构:




     




     
  • 相关阅读:
    Dubbo服务者消费者提供者案例实现
    spring核心组件
    spring为什么要注入接口
    小菜鸡进阶之路_Second week之元组、列表、集合、字典对比.
    小菜鸡进阶之路-First week
    光学公式推到——(物象位置) 1/u+1/v=1/f
    C#问题——调用事件时其他信息: 未将对象引用设置到对象的实例。
    工业相机全局曝光和卷帘曝光的区别
    相机加接圈的作用和缺点
    C#——数组维度/行数/列数/长度区别
  • 原文地址:https://www.cnblogs.com/dingfangbo/p/5768877.html
Copyright © 2020-2023  润新知