本文并不是去详细的介绍如何使用NHibernate,而是通过一个简单的例子来演示基于NHibernate的三层结构应用程序开发过程。关于NHibernate的有关文档,DDL已经做了汉化,但是由于英文文档自身就不完善,所以汉化后也是不全。菩提树在一篇《NHibernate学习之路》随笔中谈到了学习NHibernate遇到的困难,也希望大家把自己在使用NHibernate中的经验和心得能够共享出来,与大家分享。另外我也是刚开始接触NHiernate,有错误之处还请大家指点。
第一步:准备数据表
在这里用一个最简单的例子,有一张关于的用户的表,有编号,姓名,密码,Email地址和最后一次的登录时间几个字段。第二步:创建需要被持久化的类
 Create Table Users(
Create Table Users(
 LogonID varchar(20) Primary key,
    LogonID varchar(20) Primary key,
 Name varchar(40),
    Name varchar(40),
 Password varchar(20),
    Password varchar(20),
 EmailAddress varchar(40) ,
    EmailAddress varchar(40) ,
 LastLogon datetime
    LastLogon datetime
 )
)
在.NET中创建一个NHibernateWebDemo.Model的工程,添加User实体类。
第三步:创建持久化映射文件
 //User.cs
//User.cs
 using System;
using System;
 namespace NHibernateWebDemo.Model
namespace NHibernateWebDemo.Model
 {
{
 public class User
    public class User
 {
    {
 public User()
        public User()
 {
        {   
 }
        }
 private string id;
        private string id;
 private string userName;
        private string userName;
 private string password;
        private string password;
 private string emailAddress;
        private string emailAddress;
 private DateTime lastLogon;
        private DateTime lastLogon;
 public string Id
        public string Id 
 {
        {
 get { return id; }
            get { return id; }
 set { id = value; }
            set { id = value; }
 }
        }
 public string UserName
        public string UserName 
 {
        {
 get { return userName; }
            get { return userName; }
 set { userName = value; }
            set { userName = value; }
 }
        }
 public string Password
        public string Password 
 {
        {
 get { return password; }
            get { return password; }
 set { password = value; }
            set { password = value; }
 }
        }
 public string EmailAddress
        public string EmailAddress 
 {
        {
 get { return emailAddress; }
            get { return emailAddress; }
 set { emailAddress = value; }
            set { emailAddress = value; }
 }
        }
 public DateTime LastLogon
        public DateTime LastLogon 
 {
        {
 get { return lastLogon; }
            get { return lastLogon; }
 set { lastLogon = value; }
            set { lastLogon = value; }
 }
        }
 }
    }
 }
}
该文件的命名为User.hbm.xml,并且与User.cs放在同一个目录里。设置该文件的生成操作属性为“嵌入的资源”,这一点要切记。另外,使用编号当作主键,由用户输入,所以在映射文件中用assigned。
第四步:进行配置文件的设置
 <?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
 <class name="NHibernateWebDemo.Model.User, NHibernateWebDemo.Model" table="users">
        <class name="NHibernateWebDemo.Model.User, NHibernateWebDemo.Model" table="users">
 <id name="Id" column="LogonId" type="String" length="20">
               <id name="Id" column="LogonId" type="String" length="20"> 
 <generator class="assigned" />
                       <generator class="assigned" /> 
 </id>
               </id>
 <property name="UserName" column= "Name" type="String" length="40"/>
               <property name="UserName" column= "Name" type="String" length="40"/> 
 <property name="Password" type="String" length="20"/>
               <property name="Password" type="String" length="20"/> 
 <property name="EmailAddress" type="String" length="40"/>
               <property name="EmailAddress" type="String" length="40"/>
 <property name="LastLogon" type="DateTime"/>
               <property name="LastLogon" type="DateTime"/>
 </class>
        </class>
 </hibernate-mapping>
</hibernate-mapping>
在配置文件中,我们要告诉NHibernate所使用的数据库是什么,以及如何连接该数据库。
第五步:编写数据访问层的公用类
 <configSections>
<configSections>
 <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
 </configSections>
  </configSections>
 <nhibernate>
<nhibernate>
 <add key="hibernate.connection.provider"
               <add key="hibernate.connection.provider"          
 value="NHibernate.Connection.DriverConnectionProvider"/>
                       value="NHibernate.Connection.DriverConnectionProvider"/>
 <add key="hibernate.dialect"
               <add key="hibernate.dialect"                      
 value="NHibernate.Dialect.MsSql2000Dialect"/>
                       value="NHibernate.Dialect.MsSql2000Dialect"/>
 <add key="hibernate.connection.driver_class"
               <add key="hibernate.connection.driver_class"          
 value="NHibernate.Driver.SqlClientDriver"/>
                       value="NHibernate.Driver.SqlClientDriver"/>
 <add key="hibernate.connection.connection_string"
               <add key="hibernate.connection.connection_string" 
 value="server=.;uid=sa;pwd=sa;database=test"/>
                       value="server=.;uid=sa;pwd=sa;database=test"/>
 </nhibernate>
        </nhibernate>
在这里,编写了两个公用的类,分别进行Session的创建和实体的操作。在这两个类中用单件模式,来限制Session的创建。为了做到与具体的应用程序无关,在这里把程序集的名称作为参数,传递给OpenSession()方法。可以把这两个类单独放在一个名为Common的工程下,这里先把它们放在DAL层中。这两个类只是个人的一种写法,大家可以自行去编写。
第六步:编写数据访问层
 //SessionFactory.cs
//SessionFactory.cs
 using System;
using System;
 using System.Reflection;
using System.Reflection;
 using System.Data;
using System.Data;
 using NHibernate;
using NHibernate;
 using NHibernate.Cfg;
using NHibernate.Cfg;
 using NHibernate.Tool.hbm2ddl;
using NHibernate.Tool.hbm2ddl;
 namespace NHibernateWebDemo.DAL
namespace NHibernateWebDemo.DAL
 {
{
 public class SessionFactory
    public class SessionFactory
 {
    {
 public SessionFactory()
        public SessionFactory()
 {
        {
 
            
 }
        }
 private static ISessionFactory sessions;
        private static ISessionFactory sessions;
 private static Configuration cfg;
        private static Configuration cfg;
 static readonly object padlock = new object();
        static readonly object padlock = new object();
 public static ISession OpenSession(string AssemblyName)
        public static ISession OpenSession(string AssemblyName)
 {
        {
 if(sessions == null)
            if(sessions == null)
 {
            {
 lock(padlock)
                lock(padlock)
 {
                {
 if(sessions == null)
                    if(sessions == null)
 {
                    {
 BuildSessionFactory(AssemblyName);
                        BuildSessionFactory(AssemblyName);
 }
                    }
 }
                }
 }
            }
 return sessions.OpenSession();
            return sessions.OpenSession();
 }
        }
 private static void BuildSessionFactory(string AssemblyName)
        private static void BuildSessionFactory(string AssemblyName)
 {
        {
 cfg = new Configuration();
            cfg = new Configuration();
 cfg.AddAssembly(AssemblyName);
            cfg.AddAssembly(AssemblyName);
 sessions = cfg.BuildSessionFactory();
            sessions = cfg.BuildSessionFactory();
 }
        }
 }
    }
 }
}
 //EntityControl.cs
//EntityControl.cs
 using System;
using System;
 using System.Collections;
using System.Collections;
 using NHibernate;
using NHibernate;
 
 
 namespace NHibernateWebDemo.DAL
namespace NHibernateWebDemo.DAL
 {
{
 public class EntityControl
    public class EntityControl
 {
    {
 private static EntityControl entity;
        private static EntityControl entity;
 private string _AssemblyName;
        private string _AssemblyName;
 static readonly object padlock = new object();
        static readonly object padlock = new object();
 public static EntityControl CreateEntityControl(string AssemblyName)
        public static EntityControl CreateEntityControl(string AssemblyName)
 {
        {
 if(entity == null)
            if(entity == null)
 {
            {
 lock(padlock)
                lock(padlock)
 {
                {
 if(entity == null)
                    if(entity == null)
 {
                    {
 entity = new EntityControl();
                        entity = new EntityControl();
 entity._AssemblyName = AssemblyName;
                        entity._AssemblyName = AssemblyName;
 }
                    }
 }
                }
 }
            }
 return entity;
            return entity;
 }
        }
 public void AddEntity(Object entity)
        public void AddEntity(Object entity)
 {
        {
 ISession session = SessionFactory.OpenSession(_AssemblyName);
            ISession session = SessionFactory.OpenSession(_AssemblyName);
 ITransaction transaction = session.BeginTransaction();
            ITransaction transaction = session.BeginTransaction();
 try
            try
 {
            {
 session.Save(entity);
                session.Save(entity);
 transaction.Commit();
                transaction.Commit();
 }
            }
 catch(Exception ex)
            catch(Exception ex)
 {
            {
 transaction.Rollback();
                transaction.Rollback();
 throw ex;
                throw ex;
 }
            }
 finally
            finally
 {
            {
 session.Close();
                session.Close();
 }
            }
 }
        }
 public void UpdateEntity(Object entity,Object key)
        public void UpdateEntity(Object entity,Object key)
 {
        {
 ISession session = SessionFactory.OpenSession(_AssemblyName);
            ISession session = SessionFactory.OpenSession(_AssemblyName);
 ITransaction transaction = session.BeginTransaction();
            ITransaction transaction = session.BeginTransaction();
 try
            try
 {
            {
 session.Update(entity,key);
                session.Update(entity,key);
 transaction.Commit();
                transaction.Commit();
 }
            }
 catch(Exception ex)
            catch(Exception ex)
 {
            {
 transaction.Rollback();
                transaction.Rollback();
 throw ex;
                throw ex;
 }
            }
 finally
            finally
 {
            {
 session.Close();
                session.Close();
 }
            }
 }
        }
 public void DeleteEntity(object entity)
        public void DeleteEntity(object entity)
 {
        {
 ISession session = SessionFactory.OpenSession(_AssemblyName);
            ISession session = SessionFactory.OpenSession(_AssemblyName);
 ITransaction transaction = session.BeginTransaction();
            ITransaction transaction = session.BeginTransaction();
 try
            try
 {
            {
 session.Delete(entity);
                session.Delete(entity);
 transaction.Commit();
                transaction.Commit();
 }
            }
 catch(Exception ex)
            catch(Exception ex)
 {
            {
 transaction.Rollback();
                transaction.Rollback();
 throw ex;
                throw ex;
 }
            }
 finally
            finally
 {
            {
 session.Close();
                session.Close();
 }
            }
 }
        }
 public IList GetEntities(string strHQL)
        public IList GetEntities(string strHQL)
 {
        {
 IList lst;
            IList lst;
 ISession session = SessionFactory.OpenSession(_AssemblyName);
            ISession session = SessionFactory.OpenSession(_AssemblyName);
 ITransaction transaction = session.BeginTransaction();
            ITransaction transaction = session.BeginTransaction();
 
 
 lst=session.Find(strHQL);
            lst=session.Find(strHQL);
 transaction.Commit();
            transaction.Commit();
 session.Close();
            session.Close();
 return lst;
            return lst;
 }
        }
 }
    }
 }
}
创建一个名为NHibernateWebDemo.DAL的工程,数据访问层的代码编写非常简单,在创建EntityControl的实例时,需要把Model的程序集名称作为参数传入,可以通过配置文件来避免程序集名称的硬编码。
第七步:编写业务逻辑层
 //UserDAL.cs
//UserDAL.cs
 using System;
using System;
 using System.Collections;
using System.Collections;
 using NHibernateWebDemo.Model;
using NHibernateWebDemo.Model;
 namespace NHibernateWebDemo.DAL
namespace NHibernateWebDemo.DAL
 {
{
 public class UserDAL
    public class UserDAL
 {
    {
 private EntityControl control;
        private EntityControl control;
 public UserDAL()
        public UserDAL()
 {
        {
 control = EntityControl.CreateEntityControl("NHibernateWebDemo.Model");
            control = EntityControl.CreateEntityControl("NHibernateWebDemo.Model");
 }
        }
 public void AddUser(User user)
        public void AddUser(User user)
 {
        {
 control.AddEntity(user);
            control.AddEntity(user);
 }
        }
 public void UpdateUser(User user,string Id)
        public void UpdateUser(User user,string Id)
 {
        {
 control.UpdateEntity(user,user.Id);
            control.UpdateEntity(user,user.Id);
 }
        }
 public void DeleteUser(User user)
        public void DeleteUser(User user)
 {
        {
 control.DeleteEntity(user);
            control.DeleteEntity(user);
 }
        } 
 public IList GetAllUsers(string strHQL)
        public IList GetAllUsers(string strHQL)
 {
        {
 return control.GetEntities(strHQL);
            return control.GetEntities(strHQL);
 }
        }
 }
    }
 }
}
建立NHibernateWebDemo.BLL工程,为了简单期间,在业务逻辑层中我没有做任何的业务检测。
第八步:实现用户界面
 //UserBLL.cs
//UserBLL.cs
 using System;
using System;
 using System.Collections;
using System.Collections;
 using NHibernateWebDemo.DAL;
using NHibernateWebDemo.DAL;
 using NHibernateWebDemo.Model;
using NHibernateWebDemo.Model;
 namespace NHibernateWebDemo.BLL
namespace NHibernateWebDemo.BLL
 {
{
 public class UserBLL
    public class UserBLL
 {
    {
 public void AddUser(User user)
        public void AddUser(User user)
 {
        { 
 UserDAL dal = new UserDAL();
            UserDAL dal = new UserDAL();        
 dal.AddUser(user);
            dal.AddUser(user);
 }
        }
 public void UpdateUser(User user,string Id)
        public void UpdateUser(User user,string Id)
 {
        {
 UserDAL dal = new UserDAL();
            UserDAL dal = new UserDAL();
 dal.UpdateUser(user,Id);
            dal.UpdateUser(user,Id);
 }
        }
 public void DeleletUser(User user)
        public void DeleletUser(User user)
 {
        {
 UserDAL dal = new UserDAL();
            UserDAL dal = new UserDAL();
 dal.DeleteUser(user);
            dal.DeleteUser(user);
 }
        }
 public IList GetAllUsers(string strHQL)
        public IList GetAllUsers(string strHQL)
 {
        {
 UserDAL dal = new UserDAL();
            UserDAL dal = new UserDAL();
 return dal.GetAllUsers(strHQL);
            return dal.GetAllUsers(strHQL);
 }
        }
 }
    }
 }
}
用户界面很简单,这里就不给出代码了,完成后的用户界面:

 
                    
                

 
     
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号