服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

nhibernate简介 - 什么是nhibernate


  nhibernate是一个基于.net,用于关系数据库的对象持久化类库.它是着名的hibernate的.net版本.
nhibernate用于把你的.net对象持久化到底层的关系数据库中.你完全不用自己编写sql语句去操作这些对象,nh会代替你做.你的代码里面只需要关心这些对象,nh生成sql语句并能为你取到正确的东西.
开发过程
hnibernate将会有一些工具帮助你,如:生成schema,根据映射文件(mapping file)生成类,并更新schema(一个新开发者的建议).然而,在本文档中,前提是你已经手动的数据库的创建喝.net类的编写...
这里是我们要做的:
 
1.       在数据库中创建把.net类持久化的对应表.
2.       创建需要被持久化的.net类.
3.       创建映射文件,以告诉nh怎样持久化这些类的属性.
4.       创建nh的配置文件,以告诉nh怎样连接数据库.
5.       使用nh提供的api.
 
步骤1:创建数据库表
我们正在做的是一个非常简单的nh示例.在这个例子里面,我们实现一个基本的用户管理子系统.我们将会使用一个user表(sql server 2000):
 
use nhibernate
go
 
create table users (
  logonid varchar(20) not null default '0',
  name varchar(40) default null,
  password varchar(20) default null,
  emailaddress varchar(40) default null,
  lastlogon datetime default null,
  primary key  (logonid)
)
go
 
我使用的是ms sql server 2000,但是如果你找到一个任何数据库的.net data provider驱动,你可以使用任何数据库.
 
步骤2:创建.net类:
当我们这样一堆的用户的时候,我们需要某种对象来保存.nh是通过reflection对象的属性来工作的,所以我们给需要持久化的对象添加属性.一个对应于上面数据库结构的类可以写成这个样子:
 
using system;
 
namespace nhibernate.demo.quickstart
{
       public class user
       {
              private string id;
              private string username;
              private string password;
              private string emailaddress;
              private datetime lastlogon;
 
 
              public user()
              {
              }
 
              public string id
              {
                     get { return id; }
                     set { id = value; }
              }  public string username
              {
                     get { return username; }
                     set { username = value; }
              }
 
              public string password
              {
                     get { return password; }
                     set { password = value; }
              }
 
              public string emailaddress
              {
                     get { return emailaddress; }
                     set { emailaddress = value; }
              }
 
              public datetime lastlogon
              {
                     get { return lastlogon; }
                     set { lastlogon = value; }
              }
             
       }
}
 
在上面的代码里面,我们把属性和构造函数写成了public-nh并不要求一定要这样做.你可以使用public,protected,internal或者干脆private来标记你的属性.
 
步骤3:编写映射文件(mapping file)
现在我们有了数据库表和.net类,我们还需要告诉nh怎样在数据库和类之间映射.这就需要映射文件了.最简捷(也是可维护性最好的)方法就是为每一个类编写一个映射文件,如果你把命名为"xxx.hbm.xml"的映射文件和xxx类文件放在同一目录下,nh会很让 一切变得很轻松.这儿,我们的user.hbm.xml可能会像这样:
<?xml version="1.0" encoding="utf-8" ?>


<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">


    <class name="nhibernate.demo.quickstart.user, nhibernate.demo.quickstart" table="users">


  <id name="id" column="logonid" type="string(20)">

                     <generator class="assigned" />

              </id>

              <property name="username" column="name" type="string(40)"/>

              <property name="password" type="string(20)"/>

              <property name="emailaddress" type="string(40)"/>

              <property name="lastlogon" type="datetime"/>

       </class>

</hibernate-mapping>
让我们来看看这个有趣的映射文件:第一个tag是class,这里我们把类型名(类名和assembly名)映射到数据库中的user表(这里和hibernate有些不同,我们必须告诉nh这个类从哪儿来的.这个差异是由.net和java reflect机制的不同引起的-zyyang).这种情况下,我们是从assembly nhibernate.demo.quickstart中载入nhibernate.demo.quickstart.user类..nh遵守.net framework使用reflection载入类型的规则-所以遇到什么疑惑,就去查查.net framework sdk.
让我们暂时跳过"id" tag,先说property节点."name"属性值就是我们写的.net类中的属性,column属性值就是在数据库中与'net类属性对应的字段名.type属性是可选的(如果你没有标明,nh会给出一个最适合的),但是推荐的做法是带上这个属性.hibernate用户会注意到,在type属性值里,我们给出了长度值,这是因为ado.net需要这样做.
让我们返回到"id" tag,你可能会猜想这个tag和映射到表的primary key有关.正确.id  tag的格式和property tag的相似.我们从property(name)映射到目标数据库的字段(colume).
这些嵌入的generator标记告诉nh怎样生成primary key(nh很方便的就能给你生成一个,不管是什么类型的,只要你告诉它怎样去做).在我们举的例子中,把它设置成"assigned",意思是"我们的对象将自己生成key"(user对象将总是需要一个userid),如果你乐意让nh代替你生成,你会对uuid.hex和uuid.string类感兴趣的(参看chm文档).
tip:如果你使用vs.net编译,设置build action,把user.hbm.xml文件作为资源绑定到asssembly,这样映射文件就成了asssembly的一部分了.后面我们会明白这个步骤的重要性.
 
步骤4:创建数据库配置文件
目前为止,我们还没有告诉nh到哪儿去找数据库.最直接的方法就是在你程序的配置文件中给nh一个部分,就是这样:
<?xml version="1.0" encoding="utf-8" ?>

<configuration>

     <configsections>

               <section name="nhibernate" type="system.configuration.namevaluesectionhandler, system, version=1.0.3300.0,culture=neutral, publickeytoken=b77a5c561934e089" />

       </configsections>

       <nhibernate>

              <add key="hibernate.connection.provider"value="nhibernate.connection.driverconnectionprovider" />

 <add key="hibernate.dialect" value="nhibernate.dialect.mssql2000dialect" />

              <add key="hibernate.connection.driver_class" value="nhibernate.driver.sqlclientdriver" />

              <add key="hibernate.connection.connection_string" value="server=localhost;initial catalog=nhibernate;user id=someuser;password=somepwd;min pool size=2" />

       </nhibernate>

</configuration>
上面的例子中使用sqlclient驱动,连接到本地的nhibernate数据库,并且使用提供的用户和密码.还会有其他的配置项,你可以参看文档.
 
步骤5:开始体验nhibernate的神奇
所有艰苦的工作已经做完了.如果所有的工作完成后,你将会有这些成果:
æ         user.cs - 需要持久化的.net类.
æ         user.hbm.xml - 映射文件
æ         app.config - 带有ado.net连接信息的配置文件(你也可以在代码中指定的)
æ         一个叫做user的数据库表.
 
在代码里面使用nhibernate是很简单的事情:
1.       创建一个configuration对象.
2.       告诉configuration你想要持久化哪一种对象.
3.       创建一个session连接到你设定的数据库.
4.       载入,保存和查询你的对象.
5.       flush()你的session
 
好,让我们来看看一些代码:
 
创建一个configuration对象....
configuration对象知道所有在.net类和后端数据库之间的映射关系,
 
configuration cfg = new configuration();
cfg.addassembly("nhibernate.demo.quickstart");
 
configuration对象会查找这个assembly中所有以.hbm.xml结尾的文件.也有其他的方法添加映射文件,这个可能是最简单的一个.
 
创建一个session对象.......
isession对象代表着一个到后端数据库连接,itransaction代表一个nhibernate管理的事务(transaction).
 
isessionfactory factory = cfg.buildsessionfactory();
isession session = factory.opensession();
itransaction transaction = session.begintransaction();
 
载入,保存和查询你的对象......
 
现在你可以以.net的方式对待这些对象.想在数据库中保存一个新的user?只需要:
 
user newuser = new user();
newuser.id = "joe_cool";
newuser.username = "joseph cool";
newuser.password = "abc123";
newuser.emailaddress = "joe@cool.com";
newuser.lastlogon = datetime.now;
             
// tell nhibernate that this object should be saved
session.save(newuser);
 
// commit all of the changes to the db and close the isession
transaction.commit();
session.close();
 
这就是nh的好处,大部分时间内你只用关心你的业务对象(bo).
 
假如你需要根据已经知道的user id查询一个对象,如果session是open的,你只需要一行:
 
// open another session to retrieve the just inserted user


  session = factory.opensession();
user joecool = (user)session.load(typeof(user), "joe_cool");
 
这样你又会得到这个对象,设置一下对象的属性,它会在下一次flush()方法出现的时候被持久化到数据库.
 
// set joe cool's last login property
joecool.lastlogon = datetime.now;
 
// flush the changes from the session to the database
session.flush();
 
让nh去写入你对对象作出的修改,你只需要flush session就可以了.
 
更好的是,你可以从数据库中查询到一个system.collections.ilist:
 
ilist userlist = session.createcriteria(typeof(user)).list();
foreach(user user in userlist)
{
       console.writeline(user.id + " last logged in at " + user.lastlogon);
}
 
这个查询会返回整个表的内容.尤其是当你想要更多的控制时候--像类出所有在march 14, 2004 10:00 pm之后登陆过的用户,你可以:
 
ilist recentusers = session.createcriteria(typeof(user)).add(expression.gt("lastlogon", new datetime(2004, 03, 14, 20, 0, 0))).list();
foreach(user user in recentusers)
{
       console.writeline(user.id + " last logged in at " + user.lastlogon);
}
 
文档里还有很多的查询选项,但是以上这些足够让你看出hinernate的力量了.
不要忘记了,最后要关掉你的session.
 
// tell nhibernate to close this session
session.close();

扫描关注微信公众号