首页 > 代码库 > 我的NHibernate之行(一):NHibernate五部曲

我的NHibernate之行(一):NHibernate五部曲

        NHibernate是一个面向.NET环境的对象/关系数据库映射工具。对象/关系数据库映射(object/relational mapping,ORM)这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去。——百度百科



简介

        从网上找到下面的一张图,自认为这张图相当好:


        简单的说ORM,能够达到这样一种效果:我们不用去知道数据库(R)的内容,系统根据M,通过对对象(O)的操作,自动完成访问数据库。例如要完成“根据ID查询”,我们对对象使用了Get<Customer>(customerId),完成的就是这样的SQL语句:select * from Customer where CustomerId=@customerId

        很显然,带来了这两点最直观的表现:

    • “解耦”:写代码时,我们不用去管数据怎样,不用去写SQL语句。
    • OO:更符合面象对象的思想,对表的操作,都转化成对对象的操作。

        对于NHibernate,网上有这样一段评价:
    什么是优雅?动态设置,避免hardcode,就是优雅;层次清晰,层次间耦合最低,就是优雅;只写一处,处处引用,就是优雅;代码精炼,避免过度设计,就是优雅;接口明确,调用简单,就是优雅;调试容易,便于测试,就是优雅。。。。。。而优雅的设计和实现,在可扩展性、可维护性、开发效率、开发成本等方面都是最好的。
    Hibernate就是优雅的设计,它通过配置文件,建立实体与数据库的映射,动态的生成SQL语句,避免了对属性字段的hardcode,这就是它最本质的思想。



Demo结构

        对ORM就简要介绍到这。光说不练嘴把式,下面开始我们的第一个NHibernate程序。先宏观的看一下我们这个Demo:
        各层说明:
    • DomainModel(领域模型):用于持久化类和O/R Mapping操作
    • DAL(Data Access Layer数据访问层):定义对象的CRUD操作
    • NUnitTest:对数据访问层的测试,这里我使用Nunit单元测试框架
        项目引用(本程序比较简单,NHibernate相关程序集,只用到了Nhibernate.dll):
    • DAL:引用NHibernate.dll,和Domain
    • Data.Test:引用NHibernate.dll和nunit.framework.dll程序集(测试框架),Domain和DAL引用



五部曲

        接下来,是本文的重点,通过五步(传说中的五部曲)就能完成操作:
    1. 在数据库中创建把.Net类持久化的对应表.(可以不用建表,通过映射自动创建对应的表,但必须先建好数据库)
    2. 创建需要被持久化的.Net类.
    3. 创建映射文件, 告诉NHibernate怎样持久化这些类的属性.
    4. 创建NHibernate的配置文件,以告诉NH怎样连接数据库.
    5. 使用NHibernate提供的API.


一、建数据库(略)
二、编写持久化类
        新建一个Customer.cs类文件:
namespace DomainModel.Entities
{
    public class Customer
    {
        public virtual int CustomerId { get; set; }
        public virtual String FirstName { get; set; }
        public virtual String LastName { get; set; }
    }
}
        规则:NHibernate使用属性的getter和setter来实现持久化。
        注意:要求该实体类,一定不能为sealed类型,类中的字段要设置为virtual。
三、编写映射文件
        NHibernate要知道怎样去加载和存储持久化类的对象。这正是NHibernate映射文件发挥作用的地方。映射文件包含了对象/关系映射所需的元数据。元数据包含持久化类的声明和属性到数据库的映射。映射文件告诉NHibernate它应该访问数据库里面的哪个表及使用表里面的哪些字段。
        这里,我为Customer.cs类编写映射文件。新建一XML文件,命名为Customer.hbm.xml:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
  <class name="DomainModel.Entities.Customer, DomainModel" table="Customer">
    <id name="Id" type="Int32" unsaved-value=http://www.mamicode.com/"null">>        提示:我们要为Microsoft Visual Studio 2012添加编写NHibernate配置文件智能提示的功能。只要在下载的NHibernate里找到configuration.xsd和nhibernate-mapping.xsd两个文件并复制到C:\Program Files (x86)\Microsoft Visual Studio 11.0\Xml\Schemas目录即可。
        注意:XML文件的默认生成操作为“内容”,这里需要修改为“嵌入的资源”生成,因为NHibernate是通过查找程序集中的资源文件映射实体。
四、配置Nhibernate
我们可以几种方法来保存NHibernate的配置,具体以后来介绍,这里我们使用hibernate.cfg.xml文件来配置,不过不必担心,这个文件我们可以在src\NHibernate.Config.Templates文件夹下找到,直接复制到Data.Test中修改一下配置信息和文件输出属性就可以了。

注意:XML文件的默认“复制到输出目录”为“不复制”,这里需要修改为“始终复制”。
五、使用NHibernate提供的API
        1)辅助类

        我们现在可以开始NHibernate了。首先,我们要从ISessionFactory中获取一个ISession(NHibernate的工作单元)。ISessionFactory可以创建并打开新的Session。一个Session代表一个单线程的单元操作。 ISessionFactory是线程安全的,很多线程可以同时访问它。ISession不是线程安全的,它代表与数据库之间的一次操作。ISession通过ISessionFactory打开,在所有的工作完成后,需要关闭。 ISessionFactory通常是个线程安全的全局对象,只需要被实例化一次。我们可以使用GoF23中的单例(Singleton)模式在程序中创建ISessionFactory。这个实例我编写了一个辅助类NHibernateHelper 用于创建ISessionFactory并配置ISessionFactory和打开一个新的Session单线程的方法,之后在每个数据操作类可以使用这个辅助类创建ISession 。

public class SessionManager
{
    private ISessionFactory _sessionFactory;
    public SessionManager()
    {
        _sessionFactory = GetSessionFactory();
    }
    private ISessionFactory GetSessionFactory()
    {
        return (new Configuration()).Configure().BuildSessionFactory();
    }
    public ISession GetSession()
    {
        return _sessionFactory.OpenSession();
    }
}

        2)编写操作

        在Data中新建一类NHibernateSample.cs,编写一方法GetCustomerId用于读取客户信息。在编写方法之前,我们需要初始化Session。

protected ISession Session { get; set; }
public NHibernateSample(ISession session)
{
    Session = session;
}

NHibernate有不同的方法来从数据库中取回对象。最灵活的方式是使用NHibernate查询语言(HQL),是完全基于面向对象的SQL。

public void CreateCustomer(Customer customer)
{
    Session.Save(customer);
    Session.Flush();
}
public Customer GetCustomerById(int customerId)
{
    return Session.Get<Customer>(customerId);
}

测试

好了,终于可以使用我们的方法了,这里新建一个测试类NHibernateSampleFixture.cs来编写测试用例:调用NHibernateSample类中GetCustomerId方法查询数据库中CustomerId为1的客户,判断返回客户的Id是否为1。



结语

        在此章中,我们使用NHibernate来构建了一个最基本的项目,没有体现NHibernate更多细节,只描绘了NHibernate的基本面目。当然使用NHibernate有各种各样的程序架构,我按照一般模式构建的。


资料下载:
NHibernate资料

博客参考:

《NUnit详细使用方法》

《NHibernate之映射文件配置说明》

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


我的NHibernate之行(一):NHibernate五部曲