CodeSmith是我们常用的代码生成工具,其跟据不同的模板生成不同代码的方式能大大加快我们的项目开发,减少重复劳动。NHibernate模板就是其常用模板之一。从这里可以下载到最新的模板文件。现在最新的版本为NHibernate-v1.2.1.2125,可以生成NHibernate1.2,2.1,3.0的代码。我下载的稍早,是NHibernate-v1.1.7.2056,最高生成2.1的代码,不过大同小异,就以我下载的版本来进行分析吧。

基本生成操作就不说了,官网上有讲解的视频,也有大把的网友做了专门的教程。代码生成后,主要分为五大块:

1.Base块,也就是基类块,这里放有BusinessObjects块,ManagerObjects块,UnitTests块的基类,还包括一个作者提供我们的一个管理NH的ISession的小模块:NHibernateSessionManage块。

2.BusinessObjects块,也就是我们常说的实体(Entity/Model)块。里面放置着与数据库表一一对应的各个实体。

3.HbmMaps块,NH必用,不多讲。

4.ManagerObjects块,也就是我们常说的BL层,里面包括了对每个实体的操作类,命名方式类似于XXXManage等等。另外还有一个小工厂,通过不同的方法实例化不同的管理类,比较简单,不表。

5.UnitTests块,测试用例块,这不是我们今天谈的重点,故不多述。

从上面可以看到,NH模板生成的代码是典型的三层架构式代码,采用的架构模式是活动记录式。 更详细的概念描述请自行Google,或者参见我另两遍博文:业务逻辑架构模式(事务脚本,表模块,活动记录,领域模型),再谈业务逻辑架构模式(事务脚本,表模块,活动记录,领域模型)。

由于Base块里面的基类与下面三块里的子类的关系较大,所以我将按照BusinessObjects块,ManagerObjects块,NHibernateSessionManage块的顺序来讲述,在讲述的过程中直接将基类一起表述。例子就参见下面的一张图,其中Aim是实体类,AimManage是其对应的管理类。

首先是BusinessObjects块,其实我们更常见的叫法是实体层。Aim是我们自己的实体,BusinessBase<T>是其基类,其中T这个泛型是指主键的类型,如果是联合主键,这里则不会是基本类型,而是会单独生成一个类,这个类的属性与联合主键的每一个子元素一一对应。BusinessBase<T>实现了IBusinessBase<T>接口,在这个接口里规定了一个很重要的属性:Id,其类型由T来指定,这表明了所有表的主键的在代码里都叫Id。当然,如果实际的表中的主键不叫Id也是没有关系的,实体的配置文件hbm.xml可以解决这个问题。这个接口还有两个方式:GetHashCode和Equals,比较简单,不多表。

再来看ManagerObjects块,对于这我们也有更常见的叫法:BL层或者是业务逻辑层。

从上向下讲,最开始是个IManagerBase<T, TKey>接口,其中T是指其管理的实体类别,TKey是其管理的实体的主键类型。在这个接口中定义了常见的实体操作方式:增删改和各种形势的通用的查询。ManagerBase<T, TKey>类则是其具体的实现。IAimManage是具体实体管理类的接口,里面定义了具体实体所具有的特定的操作方法,注意,这里继承了IManagerBase<T, TKey>接口,这是很重要的一点,等下表述。最后是AimManage类,其继承了ManagerBase<T, TKey>类和IAimManage接口。从前者获取通用操作的实体,从后者获取定义的特定操作并由自己来实现。这里就要讲为什么IAimManage接口要继承IManagerBase<T, TKey>。从编译的角度来讲,前者不继承后者依然可以通过编译,但从我们架构代码的角度来讲,当编码中我们要操作AimManage类时,有两种方式,一种是直接通过本类型操作:

AimManage manage = new AimManage();

一种是通过接口操作:

IAimManage manage = new AimManage();

为了减少代码耦合,通过接口操作是比较理想的方式。如果前者不继承后者,当出现后者的代码时,我们就无法通过manage来操作AimManage类从ManagerBase<T, TKey>类继承到的通用操作了。换种说法,由于ManagerBase<T, TKey>类继承并实现了IManagerBase<T, TKey>接口,AimManage类又继承了ManagerBase<T, TKey>类,那么实际上AimManage类间接继承并实现了IManagerBase<T, TKey>接口。现在AimManage类又继承并实现了IAimManage接口,从多继承的角度来讲,各个接口只能操作其子类从本接口继承而来的属性与方法,如下图:

如果IAimManage接口没有继承IManagerBase接口,那当代码是这么写的时候:

IAimManage manage = new AimManage(); 

变量manage是无法执行A()方法的,因为A()方法从IManagerBase接口而来。

最后看看NHibernateSessionManage块,这是作者为我们提供的一个Session管理模块,包括两个类与两个接口。这个模块通过接口的方式与其它模块交互的少,故不多表,主要讲讲两个类的使用:NHibernateSessionManager类与NHibernateSession类。NHibernateSession类是作者为我们重新封装的Session类,他将始的ISession接口封装了进去,目的是代替NH原始的ISession接口。里面有两个重要的成员ISession和ITransaction。其中ISession就是NH的原始的ISession接口。由于他在这里将原始的ISession接口封装了进去,通过其操作事务就不是很方便,于是作者就使用成员ITransaction将ISession内的ITransaction引用出来,并写了一大堆方法来完成对事务的操作。还有一个方法:GetISession()来获取原始的ISession。

NHibernateSessionManager类是具体的Session管理类。他通过静态变量Instance实现了单例模式。他有一个重要的属性Session和一个重要的方法CreateISession()。通过Session属性来获取本次操作的NHibernateSession类。可以看到,作者将每次操作的NHibernateSession放到了缓存中(webForm与winForm放置的地方不同),提高了性能。CreateISession()方法则是真正获取原始ISession的方法,NHibernateSession类的GetISession()方法调用的也是他。

public ISession GetISession()
{
    if (iSession == null)
        iSession = NHibernateSessionManager.Instance.CreateISession();
    return iSession;
}

回到ManagerBase<T, TKey>类,在其两个构造函数中:

public ManagerBase()
    : this(NHibernateSessionManager.Instance.Session) { }
public ManagerBase(INHibernateSession session)
{
    this.session = session;
    this.session.IncrementRefCount();
}

默认就是调用NHibernateSessionManager类单例实例的Session属性,或者通过自定义INHibernateSession来注入。

以上就是代码分析的全过程,可以看出,生成的代码精干紧凑,使用方便,是我们学习三层架构模式,活动记录模式和生产实践的良好示范。

转载于:https://www.cnblogs.com/ljzforever/archive/2011/03/14/1983121.html

对使用CodeSmith模板生成NHibernate的代码的分析相关推荐

  1. CodeSmith NetTier模板生成的代码框架用法 (转)

    1.1. 概述: 使用NetTier模板生成的.net代码,包括完整的数据层,使用的技术是微软的 EnterpriseLibrary1.1版本,对应每张表都生成相对应的增删改查函数和存储过程,在查询中 ...

  2. NetTier模板生成的代码框架用法 (转)

    1.1. 概述: 使用NetTier模板生成的.net代码,包括完整的数据层,使用的技术是微软的 EnterpriseLibrary1.1版本,对应每张表都生成相对应的增删改查函数和存储过程,在查询中 ...

  3. freemarker根据模板生成word,并插入图片

    1.将你的word模板根据下图插入需要填充的占位符,格式为${},大括号内放入传对应的值 2.审核者后面放的是一张电子签名的图片,这个位置将是我们要插入图片的位置 3.然后将你的word文件保存另存为 ...

  4. 快速生成NHibernate的映射文件和映射类的利器 —— codesmith软件

    1.     Codesmith软件简介 (1) Codesmith软件是一种基于模板的代码生成工具,在ORM中,它能帮助我们生成实体类.XML配置文件,从而简化了我们一部分的开发工作,它的使用类似于 ...

  5. 创建代码生成器可以很简单:如何通过T4模板生成代码?[下篇]

    在<上篇>中我们通过T4模板为我们指定的数据表成功生成了我们需要的用于添加.修改和删除操作的存储过程.但是这是一种基于单个文件的解决方案,即我们必须为每一个生成的存储过程建立一个模板.如果 ...

  6. [转]MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码

    本文转自:http://www.cnblogs.com/guomingfeng/p/mvc-ef-t4.html 〇.目录 一.前言 二.工具准备 三.T4代码生成预热 (一) 单文件生成:Hello ...

  7. JavaScript实现模板生成大量数据的方法(附代码)

    本篇文章给大家带来的内容是关于JavaScript实现模板生成大量数据的方法(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 有时需要根据模板生成大量数据,这个代码工具简直就 ...

  8. JAVA实现模板word文档导入,Java依据word模板生成word文档之后台解析和实现及部分代码(一)...

    Java根据word模板生成word文档之后台解析和实现及部分代码(一) 后台主要工作是解析XML定义的标签文件,并获取到数据集,放入到Map中,然后调用Jacob.jar中提供的相关方法来实现替换. ...

  9. velocity笔记(一)什么是velocity,我们什么时候会使用到这个,基本语法,利用模板生成实体类的各层代码

    目录 什么是velocity 应用场景 组成结构 快速入门 总结 基本语法 注释 非解析内容 引用 变量引用 属性引用 方法引用 指令 流程控制指令 #set 指令 #if/#elseif/#else ...

最新文章

  1. 2022-2028年中国中密度纤维板市场投资分析及前景预测报告
  2. 顶配版阿里大佬面试笔记+300道硬核面试题,跪着啃完了。。。。
  3. 用Tableau画可调整的树状图(Tree Diagram)
  4. Python之pandas:pandas中to_csv()、read_csv()函数的index、index_col(不将索引列写入)参数详解之详细攻略
  5. MyBatis 实际使用案例-编程式使用
  6. 华为可以分屏吗_华为手机经常弹出“系统更新”提示,可以不更新吗?看完涨知识了...
  7. Knockout中ko.utils中处理数组的方法集合
  8. idea2021部署maven+javaweb项目到jboss(diy)
  9. java 验证码透明背景_Java中的证书透明度验证
  10. python f.write 保存图片到路径_Python实现生成图片路径和对应标签的方式
  11. 小技巧 ----- Java中指定保留几位小数
  12. plink 与 ssh 远程登录问题
  13. Redis Command
  14. python 并行_python多进程并行代码实例
  15. html中怎么给文字设置动画效果,文字效果怎么设置?
  16. ofd阅读器qt_GitHub - gogo123150/ofdEditor: 一个很简陋的ofdEditor
  17. 【2019年5月23日】指数估值排名
  18. win7共享中心服务器运行失败,Win7系统网络与共享中心无法打开怎样解决?
  19. Centos 7.5 1804 镜像下载
  20. vscode 修改注释颜色

热门文章

  1. html5 --- IDBDatabase创建对象存储和索引
  2. ES6-18/19 异步的开端-promise
  3. 61-1 认识webpack
  4. 百年难得一见!阿里园区惊现双月争辉奇观!
  5. 有了螃蟹让心情好一点
  6. 编写高性能的托管应用程序:入门
  7. ORB-SLAM2中四叉树管理特征点
  8. caffe 初学参考链接
  9. python编程入门第一课_python入门前的第一课 python怎样入门
  10. python元组和列表的联系_Python元组与列表的区别和联系?