本文并不是去详细的介绍如何使用NHibernate,而是通过一个简单的例子来演示基于NHibernate的三层结构应用程序开发过程。关于NHibernate的有关文档,DDL已经做了汉化,但是由于英文文档自身就不完善,所以汉化后也是不全。菩提树在一篇《NHibernate学习之路》随笔中谈到了学习NHibernate遇到的困难,也希望大家把自己在使用NHibernate中的经验和心得能够共享出来,与大家分享。另外我也是刚开始接触NHiernate,有错误之处还请大家指点。
本文并不是去详细的介绍如何使用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

)
第二步:创建需要被持久化的类
在.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);

}

}

}
第八步:实现用户界面
用户界面很简单,这里就不给出代码了,完成后的用户界面:

完整代码下载:/Files/Terrylee/NHibernateWebDemo.rar
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?