开始使用NHibernate

好久没有写日志了,今天有些时间,谢谢.NET中的持久化框架技术NHibernate

我们很多人都用过Java的持久化框架技术Hibernate,实现ORM机制。在.NET中同样可以实现相同操作,采用类似于Hibernate的NHibernate。本文章主要介绍NHibernate的使用,在后续的文章中详细的深入。

NHibernate几乎和Java中的Hibernate一样,无论是会话工厂、会话、事务处理、多表映射等等,都是差不多的。

首先需要准备NHIbernate的必备组件,可以到http://downloads.sourceforge.net/nhibernate/NHibernate-1.2.0.CR1.msi?modtime=1172161735&big_mirror=0 下载。然后安装。

可以安装到你想要安装的目录中,其中包含bin、doc、src三个目录

其中bin目录包含.NET1.1和.NET2.0的必备组件;doc包含帮助文档,src当然是源代码了

在此我用Viso2003进行演示,使用.NET1.1中的必备组件

首先建立一个ASP.NET工程,在此命名为FirstUser

添加引用,引用.NET1.1必备组件的NHibernate.dll

修改其中的web.config配置文件。在此web.config配置文件类似于hibernate.cfg.xml,包含SessionFactory的配置信息。在NHibernate中可以采用web.xml或者hibernate.cfg.xml作为hibernate的默认配置文件。在此采用web.config。

修改内容如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
   name="hibernate-configuration"
   type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"
   />
</configSections>

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
   <session-factory>
   <property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>
   <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
   <property name="connection.connection_string">Server=127.0.0.1;Uid=sa;Pwd=;Database=BookDB</property>
   <mapping assembly="FirstUser"/>
      </session-factory>
</hibernate-configuration>

  
<system.web>

       .................................

</system.web>

</configuration>

其中声明配置节hibernate-configuration,类型为NHibernate.Cfg.ConfigurationSectionHandler, NHibernate。这样NHibernate可以读取hibernate-configuration配置节中的配置信息。

hibernate-configuration的配置信息配置sessionFactory,当然是配置数据库的连接等信息。在此增加三个属性节点,分别配置“方言”、“连接提供者”、“连接字符串”。由于在此数据库采用MSSQL2000,所以不用提供数据库驱动(.NET自带),如果是其他数据库,例如MSSQL,需要配置驱动信息。

最后包含自节点<mapping assembly="FirstUser"/>指明对程序集(当前的工程)FirstUser下的实体类进行映射。

好了,现在可以开始写持久化类了。在Java中卫POJO类,在.NET中称为POCO类(Plain Ordinary CLR Objects)。此类和数据库中的表产生映射关系。在数据库中建立UserInfo表,包含三个字段,分别为userid,username,userpass

其中userid为自增类型(identity(1,1)),其余为varchar类型。

建立的持久化类包含在子命名空间poco中(当然也可以直接放在根命名空间FirstUser中,在此进行有效的组织)。

using System;

namespace FirstUser.poco
{
/// <summary>
/// UserInfo 的摘要说明。
/// </summary>
public class UserInfo
{
   private int id;
   public virtual int Id
   {
    get{ return this.id;}
    set{ this.id=value;}
   }
   private string username;
   public virtual string Username
   {
    get{ return this.username;}
    set{ this.username=value;}
   }
   private string userpass;
   public virtual string Userpass
   {
    get{ return this.userpass;}
    set{ this.userpass=value;}
   }
   public UserInfo()
   {
    //
    // TODO: 在此处添加构造函数逻辑
    //
   }
}
}

其中注意:主键数据成员名称为id,而且所有的属性为virtual(虚属性)形式

下面再工程下建立映射文件(hbm.xml)。名称为UserInfo.hbm.xml。内容如下:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="FirstUser.poco" assembly="FirstUser">
<class name="UserInfo" table="UserInfo">
<id name="Id">
   <column name="userid"/>
   <generator class="identity"/>
</id>
<property name="Username">
   <column name="username"/>
</property>
<property name="Userpass">
   <column name="userpass"/>
</property>
</class>
</hibernate-mapping>

其中红体部分指明映射的类包含在poco的子命名空间中,兰体部分指明映射的类在FirstUser程序集中。映射方式和Java的Hibernate一样(自己理解吧)。

众所周知,在采用Hibernate做持久化操作的时候,需要建立会话工程。会话工程会根据配置文件(web.config)中的配置产生,以便知道如何进行数据库连接。会话工厂产生会话(Session),会话负责完成持久化的具体操作。

会话工厂一般只需要产生一个,然后多次使用。除非同时连接不同的数据库。所有可以建立一个工具类得到会话工厂。此工具类为工厂类型是,负责产生会话工程,并由使用者取得,进而产生会话。

在此使用单态模式,保证会话工厂的实例唯一。

using System;
using System.Web;
using NHibernate;
using NHibernate.Cfg;
namespace FirstUser.rule
{
/// <summary>
/// NHibernateHelper 的摘要说明。
/// </summary>
public sealed class NHibernateHelper
{
   /// <summary>
   /// CurrentSessionKey为保存在http上下文中的当前会话的键值
   /// </summary>
   private const string CurrentSessionKey="nhibernate.current_session";
   private static readonly ISessionFactory sessionFactory;
   /// <summary>
   /// 通过web.config配置文件建立会话工厂,此会话工厂为单态新式
   /// </summary>
   static NHibernateHelper()
   {
    sessionFactory = new Configuration().Configure().BuildSessionFactory();
   }
   /// <summary>
   /// 得到Http上下文保存的会话实例。如果会话不存在,则创建,并保存到Http上下文中
   /// </summary>
   /// <returns></returns>
   public static ISession GetCurrentSession(){
    HttpContext context = HttpContext.Current;
    ISession currentSession=context.Items[CurrentSessionKey] as ISession;
    if(currentSession==null)
    {
     currentSession = sessionFactory.OpenSession();
     context.Items[CurrentSessionKey] = currentSession;
    }
    return currentSession;
   }
   /// <summary>
   /// 关闭当前会话,并将会话从Http上下文中清除
   /// </summary>
   public static void CloseSession()
   {
    HttpContext context = HttpContext.Current;
    ISession currentSession = context.Items[CurrentSessionKey] as ISession;
    if(currentSession==null)
    {
     return ;
    }
    currentSession.Close();
    context.Items.Remove(CurrentSessionKey);
   }
   /// <summary>
   /// 关闭会话工厂
   /// </summary>
   public static void CloseSessionFactory()
   {
    if(sessionFactory!=null)
     sessionFactory.Close();
   }
}
}

上述工具类参考了NHibernate的帮助文档。为了便于组织,将上述的类放入rule子命名空间中

开始进行测试了。

建立一个普通的aspx页面,放入两个TextBox,分别用来收集用户输入的用户名和密码。放入一个Button,在click事件中编写如下代码,保存输入的用户名和密码。

ISession session = NHibernateHelper.GetCurrentSession();
    ITransaction tx = session.BeginTransaction();
    UserInfo   user= new UserInfo();
    user.Username   = txtUsername.Text.Trim();
    user.Userpass   = txtUserpass.Text.Trim();
    session.Save(user);
    tx.Commit();
    NHibernateHelper.CloseSession();

 

类中需要引用如下的命名空间,以便实现NHibernate操作

using NHibernate;
using NHibernate.Cfg;

运行测试,看看是否将数据保存到了数据库中

posted @ 2009-08-04 11:44  awp110  阅读(175)  评论(0编辑  收藏  举报