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