[本文为转载文章]
 
什么是NHibernate
 
NHibernate 是一个基于.Net 的针对关系型数据库的对象持久化类库。Nhibernate 来源于非常优秀的基于Java的Hibernate 关系型持久化工具。
NHibernate 从数据库底层来持久化你的.Net 对象到关系型数据库。NHibernate 为你处理这些,远胜于你不得不写SQL去从数据库存取对象。你的代码仅仅和对象关联,NHibernat 自动产生SQL语句,并确保对象提交到正确的表和字段中去。
 
为什么写这个指南
 
任何熟悉Hibernate的人会发现这篇指南和Glen Smith 的 A Hitchhiker's Guide to Hibernate 非常相近。这里的内容正是基于他的指南,因此所有的感谢都应该给与他。
NHibernate的文档并非每处都和Hibernate的文档一致。然而,项目的相似应该能使读者通过读Hibernate的文档来很好的理解NHibernate如何工作。
这篇文档意在让你尽可能快的开始使用NHibernate。它将介绍如何持久化一个简单的对象到一张表里。想得到更多的复杂的例子,可以参考NUnit测试及附带代码。
 
开发的过程
 
Nhibernate未来将会提供一些工具帮助你自动产生schema文件(现在还是基于代码)或是通过映射文件产生类(在筹措阶段)或是更新schema(来自于一个新开发者的建议)。然而,这里我们的例子是假定一切来自于完全手写,包括设置表和.Net类的编写。我们将进行以下步骤。
1.新建一个将要持久化.Net对象的表
2.构建一个需要被持久化的.Net类
3.构建一个可以让NHibernate知道如何持久化对象属性的映射文件
4.构建一个让NHibernate知道如何连接数据库的配置文件]
5.使用NHibernate的API
 
第一步:写构建表的SQL
 
这里我们将使用的是一个非常简单的例子。假设你正在为你的网站开发一个基本的用户管理子系统。我们将使用如下的一张User表(假定你已经设置好一个数据库—在的例子里我称它为NHibernate)。 
              
NHibernate 快速指南use NHibernate
NHibernate 快速指南
go
NHibernate 快速指南 
NHibernate 快速指南
CREATE TABLE users (
NHibernate 快速指南  LogonID 
nvarchar(20NOT NULL default '0',
NHibernate 快速指南  Name 
nvarchar(40default NULL,
NHibernate 快速指南  Password 
nvarchar(20default NULL,
NHibernate 快速指南  EmailAddress 
nvarchar(40default NULL,
NHibernate 快速指南  LastLogon 
datetime default NULL,
NHibernate 快速指南  
PRIMARY KEY  (LogonID)
NHibernate 快速指南)
NHibernate 快速指南
go

我使用的是MS Sql Server 2000, 但也可以使用任何数据库,只要你有关于它们的基于.Net数据提供驱动程序。我们将得到一个含有LogonID,Name, Password, Email 和LastLogon的表. 经过以上标准步骤,我们下一步是写一个.Net类处理一个给定的User对象。

第二步:产生一个.Net 类文件
 
当内存中有一堆User对象的时候,我们需要某种对象去保存它们。NHibernate通过对象属性的反射来工作,因此我们需要添加我们希望持久化的对象属性。一个可以被NHibernate持久化的类应该看起来象下面的样子:
              
NHibernate 快速指南using System;
NHibernate 快速指南 
NHibernate 快速指南
namespace NHibernate.Demo.QuickStart


在上面的例子里,我们的属性和构建函数 是public,但这个对NHibernate不是必要的.它可以使用public, protected, internal或者甚至是用private来持久化数据。
 
第三步:写映射文件

现在我们有数据表和需要去映射它的.Net类。我们需要一种方式去让NHibernate知道如何从一个映射到另一个。这个任务依赖于映射文件来完成。最易于管理的办法是为每一个类写一个映射文件,如果你命名它是YourObject.hbm.xml 并且把它放在和类的同一个目录里,NHiberante将会使得事情简单起来。下面是一个User.hbm.xml的例子:
               
NHibernate 快速指南<?xml version="1.0" encoding="utf-8" ?>
NHibernate 快速指南
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
NHibernate 快速指南        
<class name="NHibernate.Examples.QuickStart.User, NHibernate.Examples" table="users">
NHibernate 快速指南               
<id name="Id" column="LogonId" type="String" length="20"> 
NHibernate 快速指南                       
<generator class="assigned" /> 
NHibernate 快速指南               
</id> 
NHibernate 快速指南               
<property name="UserName" column= "Name" type="String" length="40"/> 
NHibernate 快速指南               
<property name="Password" type="String" length="20"/> 
NHibernate 快速指南               
<property name="EmailAddress" type="String" length="40"/>
NHibernate 快速指南               
<property name="LastLogon" type="DateTime"/>
NHibernate 快速指南        
</class>
NHibernate 快速指南 
NHibernate 快速指南
</hibernate-mapping>

              
让我们来看看这个文件中让我们感兴趣的某些行。第一个有趣的标签是class。这里我们将映射类型名称(类名和装配件)到我们数据库中的User表,这里和Hibernate有一点点的不同。你将不得不告诉NHibernate从何处提取对象。在这个例子里我们从装配件NHibernate.Examples装载类NHibernate.Examples.QuickStart.User 。NHibernate 遵循和.Net Framework同样的规则来加载类型。因此如果你在如何指定类型的方面有些混淆,请参看.Net Framework SDK。
让我们先跳过id标签,来讨论property标签。简要看一下,你将发现NHibernate所要做的工作。name属性的值正是我们.Net 类的属性,column属性值将是我们数据库里的字段。type属性是可选的(如果你不标明,NHibernate将利用反射进行最佳的推测)。
好了,让我们回到标签id, 你可以猜测到这个标签将是映射数据库表的主键,的确如此,id标签的组成和我们刚才看的property标签是相似的。我们映射属性到目标数据库的字段。
内嵌的generator 标签告诉NHibernate 如何生成主键(它将恰当的为你生成主键,不管你指定何种类型,但你必须告诉它)。在我们的例子里,我们设定为assigned,意味着我们对象将自己生成主键(毕竟User对象常常需要一个UserID)。如果你执意要NHiberante为你生成主键,你感兴趣于设定uuid.hex和uuid.string(从文档中获取更多信息)
 
提示:如果你使用Visual Studio.Net 去编译的话,请将user.hbm.xml的Build Action属性设置为Embedded Resource。映射文件将成为装配件的一部分。更详细的细节重点将在后面展示。
提示:如果你仅仅是改变映射文件,你不能使用build 而应该Rebuild项目。Visual Studio.Net 不会重新编译有改变的映射文件。
 
第四步:为你的数据库产生一个配置文件

我们至今还没有告诉NHibernate 去哪里连接数据库。最直接的办法是在你的应用程序的配置文件里设置一个NHibernate配置节。这和在Hibernate里使用属性文件是等价的。如下配置:
               
NHibernate 快速指南<?xml version="1.0" encoding="utf-8" ?>
NHibernate 快速指南
<configuration>
NHibernate 快速指南        
<configSections>
NHibernate 快速指南               
<section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
NHibernate 快速指南        
</configSections>
NHibernate 快速指南        
NHibernate 快速指南        
<nhibernate>
NHibernate 快速指南               
<add 
NHibernate 快速指南                       
key="hibernate.connection.provider"          
NHibernate 快速指南                       value
="NHibernate.Connection.DriverConnectionProvider" 
NHibernate 快速指南               
/>
NHibernate 快速指南               
<add 
NHibernate 快速指南                       
key="hibernate.dialect"                      
NHibernate 快速指南                       value
="NHibernate.Dialect.MsSql2000Dialect" 
NHibernate 快速指南               
/>
NHibernate 快速指南               
<add 
NHibernate 快速指南                       
key="hibernate.connection.driver_class"          
NHibernate 快速指南                       value
="NHibernate.Driver.SqlClientDriver" 
NHibernate 快速指南               
/>
NHibernate 快速指南               
<add 
NHibernate 快速指南                       
key="hibernate.connection.connection_string" 
NHibernate 快速指南                       value
="Server=localhost;initial catalog=nhibernate;Integrated Security=SSPI" 
NHibernate 快速指南               
/>
NHibernate 快速指南        
</nhibernate>
NHibernate 快速指南
</configuration>
NHibernate 快速指南

              
上面的例子里用了SqlClient 驱动,在本地连接名称为NHibernate 的数据库,提供用户名和密码。那里有一堆属性你需要调整来确定如何让NHibernate来访问数据库。再次说明,你可以在文档里获取更多信息。
请注意以上的配置里并没有涉及到log4net的配置信息。NHibernate使用log4net来记录内部发生的一切。在一个应用程序产品里,在你特定环境里,我推荐配置log4net,并为NHibernate设置一定的日志级别。

第五步:开始展现NHibernate的魔力
 
所有艰苦的工作已经完成。你将有以下内容
User.cs ----你需要持久化的C#类
User.hbm.xml ----你的NHibernate映射文件
App.config ---对ADO.NET连接的配置信息(如果你愿意,你可以在代码中实现)。
你的数据库里有一张User表。
 
现在可以在你的代码中恰当简洁的使用NHibernate。简化的版本如下
创建一个Configuration对象
让Configuration知道你将存储何种类型的对象
为你选择的数据库创建一个Session对象
Load,Save和Query你的对象
通过Session的Flush()方法将对象提交给数据库。
 
为了让你更清晰,我们来看一些代码。

首先,创建一个Configuration对象
Configuration对象能够解析所有.Net对象和后台数据库中的映射关系。
 
NHibernate 快速指南               
NHibernate 快速指南        Configuration cfg 
= new Configuration();
NHibernate 快速指南        cfg.AddAssembly(
"NHibernate.Examples");

              
Configuration对象会搜索装配件里的任何以hbm.xml 结尾的文件。还有其他方法加载映射文件,但这种方式是最简单的。
下一步,创建一个Session对象
ISession对象提供一个到后台数据库的连接,ITransaction对象提供一个可以被NHibernate管理的事务。
 
NHibernate 快速指南               
NHibernate 快速指南        ISessionFactory factory 
= cfg.BuildSessionFactory();
NHibernate 快速指南        ISession session 
= factory.OpenSession();
NHibernate 快速指南        ITransaction transaction 
= session.BeginTransaction();
NHibernate 快速指南              
 
 
接着来Load, Save和Query你的对象
现在你可以用使用传统的.Net方法来操纵对象。你想保存一个新对象到数据库吗?尝试下面的方法:
               
NHibernate 快速指南        User newUser = new User();
NHibernate 快速指南        newUser.Id 
= "joe_cool";
NHibernate 快速指南        newUser.UserName 
= "Joseph Cool";
NHibernate 快速指南        newUser.Password 
= "abc123";
NHibernate 快速指南        newUser.EmailAddress 
= "joe@cool.com";
NHibernate 快速指南        newUser.LastLogon 
= DateTime.Now;
NHibernate 快速指南                       
NHibernate 快速指南        
// Tell NHibernate that this object should be saved
NHibernate 快速指南
        session.Save(newUser);
NHibernate 快速指南 
NHibernate 快速指南        
// commit all of the changes to the DB and close the ISession
NHibernate 快速指南
        transaction.Commit();
NHibernate 快速指南        session.Close();

 
正如你所看到的,关于NHiberante重要的事情是如此简单。继续并且查询你的数据库,验证一下User表里的新记录。现在重要的事情就是你去操心业务对象并在进行处理的时候告诉NHibernate就可以了。
 
让我们来告诉你,当你有一个UserID的时候如何获取对象(举例说,登陆你的网站的时候)。仅仅一句话就可以打开Session,传入key就可以了
               
NHibernate 快速指南        // open another session to retrieve the just inserted user
NHibernate 快速指南
        session = factory.OpenSession();
NHibernate 快速指南 
NHibernate 快速指南        User joeCool 
= (User)session.Load(typeof(User), "joe_cool");
NHibernate 快速指南

你所获取的User对象还在生存周期内!改变它的属性,并通过Flush()持久化到数据库。
               
NHibernate 快速指南        // set Joe Cool's Last Login property
NHibernate 快速指南
        joeCool.LastLogon = DateTime.Now;
NHibernate 快速指南 
NHibernate 快速指南        
// flush the changes from the Session to the Database
NHibernate 快速指南
        session.Flush();
 
你所要做的就是通过NHibernate来进行你需要的改变,并调用Session的Flush()方法提交。验证一下数据库,查查用户ID为”joe_cool”的记录中”LastLogon”的更改。
 
还有更好的,你可以以System.Collections.IList的方式来获取从表中的对象。如下
               
NHibernate 快速指南        IList userList = session.CreateCriteria(typeof(User)).List();
NHibernate 快速指南        
foreach(User user in userList)

这个查询将会返回所有表记录。往往你需要做更多的控制,比如说获取从March 14, 2004 10:00 PM 以后登陆的用户,如下:
               
NHibernate 快速指南        IList recentUsers = session.CreateCriteria(typeof(User))
NHibernate 快速指南                                      .Add(Expression.Expression.Gt(
"LastLogon"new DateTime(200403142000)))
NHibernate 快速指南                                      .List();
NHibernate 快速指南 
NHibernate 快速指南        
foreach(User user in recentUsers)
               
 
文档里还有一堆健壮的查询方式让你调用,这里仅仅让你对NHibernate所提供的强有力的工具有一定的了解。
       
最后调用Session对象的Close()方法,释放NHibernate所使用的ADO.Net连接资源
 
               
NHibernate 快速指南        // tell NHibernate to close this Session
NHibernate 快速指南
        session.Close();

更确切地说…
 
你已经完成创建对象,持久化并通过条件查询或键值查询来返回它。相信你已经从中获得快乐。
现在你对NHibernate有了大致的了解,如果你能仔细阅读大量来自Hibernate 2.0.3文档,你将获得帮助(NHibernate文档还在早期阶段,现在还仅仅是对Hibernate的拷贝)。
 
Enjoy! And Happy NHibernating!
Mike Doerfler
 
再次说明,所有的权利来自Glen Smith的A Hitchhiker's Guide to Hibernate
 
 
Translated by:  Jason Xie
Published: 2005-02-24
 
 
 

相关文章: