比较老了,而且用Vs2005编译还有问题,没有进行排错,不过,里面的架构还是有用的,还是转帖保存下的好。
=======================================================================
本文并不是去详细的介绍如何使用
NHibernate
,而是通过一个简单的例子来演示基于
NHibernate
的三层结构应用程序开发过程。关于
NHibernate
的有关文档,
DDL
已经做了汉化,但是由于英文文档自身就不完善,所以汉化后也是不全。菩提树在一篇《
NHibernate学习之路
》随笔中谈到了学习
NHibernate
遇到的困难,也希望大家把自己在使用
NHibernate
中的经验和心得能够共享出来,与大家分享。另外我也是刚开始接触
NHiernate
,有错误之处还请大家指点。
第一步:准备数据表
在这里用一个最简单的例子,有一张关于的用户的表,有编号,姓名,密码,
Email
地址和最后一次的登录时间几个字段。
第二步:创建需要被持久化的类
Create
Table
Users(
LogonID varchar ( 20 ) Primary key ,
Name varchar ( 40 ),
Password varchar ( 20 ),
EmailAddress varchar ( 40 ) ,
LastLogon datetime
)
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; }
}
}
}
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 >
< 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 >
< 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();
}
}
}
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;
}
}
}
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);
}
}
}
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);
}
}
}
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);
}
}
}
用户界面很简单,这里就不给出代码了,完成后的用户界面: