我的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、NHibernate.ByteCode.LinFu.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.2">
  <class name="DomainModel.Entities.Customer, DomainModel" table="Customer">
    <id name="Id" type="Int32" unsaved-value="null">
      <column name="CustomerId" sql-type="int" not-null="true" unique="true"/>
      <generator class="native" />
    </id>
    <property name="Firstname" type="String">
      <column name="Firstname" sql-type="nvarchar" not-null="false"/>
    </property>
    <property name="Lastname" type="String">
      <column name="Lastname" sql-type="nvarchar" not-null="false"/>
    </property>
  </class>
</hibernate-mapping>
        提示:我们要为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 version="1.0" encoding="utf-8"?>
<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
    <session-factory>
        <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
        <property name="connection.connection_string">
            Data Source=.\SQLEXPRESS;Initial Catalog=NHibernateSample;
      Integrated Security=True;Pooling=False
        </property>
        <property name="adonet.batch_size">10</property>
        <property name="show_sql">true</property>
        <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
        <property name="use_outer_join">true</property>
        <property name="command_timeout">10</property>
        <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
     <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, 
      NHibernate.ByteCode.Castle</property>
    <mapping assembly="NHibernateSample.Domain"/>    
    </session-factory>
</hibernate-configuration>
        注意: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 NHibernateHelper
{
    private ISessionFactory _sessionFactory;
    public NHibernateHelper()
    {
        _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。

namespace NUnitTest
{
    [TestFixture]
    public class NHibernateSampleFixture
    {
        private NHibernateSample _sample;
        private ISession _session;
        private NHibernateHelper _helper;
        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            _helper = new NHibernateHelper();
        }
        [SetUp]
        public void Setup()
        {
            _session = _helper.GetSession();
            _sample = new NHibernateSample(_session);
        }
        [Test]
        public void GetCustomerByIdTest()
        {
            var tempCutomer = new Customer { FirstName = "连海", LastName = "张" };
            _sample.CreateCustomer(tempCutomer);
            Customer customer = _sample.GetCustomerById(1);
            int customerId = customer.CustomerId;
            Assert.AreEqual(1, customerId);
        }
    }
}



结语


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




资料下载
NHibernate资料

博客参考:

《NUnit详细使用方法》

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

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


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 40
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 40
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值