由于本人在项目工作中一直致力于NH的开发,下面是自己对NH中的总结,以及碰到的问题的解决方法。
NH的架构
一、体系结构
首先我们来看看NHibernate的体系结构:
NHibernate是数据库和应用程序之间的持久化层,应用程序和NHibernate通过持久化(Persistent)对象联系在一起。NHibernate使用app.config或者web.config和映射文件进行设置。
下面来看看怎么使用NHibernate API的一个最小子集。
下面是图中一些对象的定义:
Configuration(NHibernate.Cfg.Configuration)
配置对象,用来指定用来出创建ISessionFactory的属性和映射文件。(图中没有此对象)
SessionFactory (NHibernate.ISessionFactory)
Session的工厂。
会话,Session (NHibernate.ISession)
代表应用程序和持久化层之间的一次对话。封装了一个ADO.NET连接。也是Transaction的工厂。保存有必需的(第一级)持久化对象的缓存,用于遍历对象图,或者通过标识符查找对象。
事务Transaction (NHibernate.ITransaction)
(可选) 单线程,生命期短促的对象,应用程序用它来表示一批工作的原子操作。是底层的ADO.NET事务的抽象。一个Session某些情况下可能跨越多个Transaction 事务。
二、示例代码
我们看看他们是如何协同工作的,请看下面的代码。
代码示例(未改变数据库中的数据,查询操作):
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
1
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
8
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
12
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
Configuration的Configure方法,将使用应用程序的配置文件或者hibernate.cfg.xml文件的<hibernate-configuration>节点进行配置,返回值是一个配置好了的Configuration对象的实例。
然后这个Configuration通过BuildSessionFactory方法创建ISessionFactory的实例。
ISessionFactory的实例通过OpenSession打开一个ISession的实例,用这个实例完成数据库的操作,然后关闭它。
如果你的代码中需要事务,只需要把代码稍微修改一下。
代码示例(改变了数据库中的数据,数据的增删改):
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
1 //配置Configuration
2 Configuration cfg = new Configuration().Configure();
3 //创建ISessionFactory
4 ISessionFactory factory = cfg.BuildSessionFactory();
5 //定义事务
6 ITransaction tx = null;
7 //打开ISession
8 ISession session = factory.OpenSession();
9 try
10 {
11 //开始事务
12 tx = session.BeginTransaction();
13 在这里添加操作
14 tx.Commit();
15 }
16 catch(HibernateException ex)
17 {
18 if (tx!=null) tx.Rollback();
19 throw ex;
20 }
21 finally
22 {
23 //关闭ISession
24 session.Close();
25 }
26
我一般在不影响数据的方法(例如:查询)中不包含事务,而影响数据的方法(例如:增删改)使用事务。
由于在本项目中使用了spring.net,所以上述的confing,sessionfactory,session操作都由一个由spring提供的hibernateTemplete提供,一般的操作就不用在程序中显示的调用confing, sessionfactory,session接口了。
NH的Config配置文件
< object id ="DbProvider" type ="Spring.Data.Common.DbProviderFactoryObject,Spring.Data" >
< property name ="Provider" value ="SqlServer-2.0" />
< property name ="ConnectionString" value ="Data Source=192.168.0.84;Database=eChecking;User ID=sa;Password=davey@citiz.net" />
</ object >
<!-- 以下設置物件與資料庫表格映射文件 -->
< object id ="SessionFactory" type ="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate12" >
< property name ="DbProvider" ref ="DbProvider" />
< property name ="MappingAssemblies" > < list >
< value > Inter.eCheck.Entity </ value >
< value > Inter.eCheck.Dao </ value >
</ list >
</ property >
< property name ="HibernateProperties" >
< dictionary >
<!-- SQL方言,這邊設定的是MSSQL2005 -->
< entry key ="hibernate.connection.provider" value ="NHibernate.Connection.DriverConnectionProvider" />
< entry key ="hibernate.dialect" value ="NHibernate.Dialect.MsSql2005Dialect" />
< entry key ="hibernate.connection.driver_class" value ="NHibernate.Driver.SqlClientDriver" />
<!-- 顯示實際操作資料庫時的SQL -->
< entry key ="show_sql" value ="true" />
</ dictionary >
</ property >
</ object >
映射文件的基本配置
<!-- 指出是NH1.2版本 -->
< hibernate-mapping xmlns ="urn:nhibernate-mapping-2.2" >
<!--用class元素来定义一个持久化类 -->
< class name ="Inter.eCheck.Entity.Unit, Inter.eCheck.Entity" table ="Unit" lazy ="false" >
<!—ID -->
< id name ="Id" type ="Int32" unsaved-value ="0" >
< column name ="Id" length ="4" sql-type ="int" not-null ="true" unique ="true" index ="PK_Unit" />
<!-- 用来为该持久化类的实例生成唯一的标识 -->
< generator class ="native" />
</ id >
<!—类属性及数据库字段映射 -->
< property name ="Code" type ="String" >
< column name ="Code" length ="50" sql-type ="varchar" not-null ="true" />
</ property >
< property name ="ChineseName" type ="String" >
< column name ="ChineseName" length ="50" sql-type ="nvarchar" not-null ="true" />
</ property >
< property name ="EnglishName" type ="String" >
< column name ="EnglishName" length ="50" sql-type ="varchar" not-null ="true" />
</ property >
< property name ="IsDecimal" type ="Int32" >
< column name ="IsDecimal" length ="4" sql-type ="int" not-null ="true" />
</ property >
</ class >
</ hibernate-mapping >
实体类:
// 编写时间:2009年1月5号
// 作用:定义实体对象Unit的基本属性
// ===============================================================================
using System;
namespace Inter.eCheck.Entity
{
/// <summary>
/// 单位信息实体对象
/// </summary>
[Serializable]
public class Unit
{
/// <summary>
/// 构造函数
/// </summary>
public Unit() { }
#region UnitEntity
private int id; // 单位表ID
private string code; // 单位表编号
private string Detail; // 单位中文名
private string xs; // 本类单位标准
private string rate; // 换算比率
private string flag; // 标志(0:非重量单位,1:重量单位)
private int decFlag; // 小数标志(0:不允许小数,1:允许小数)
private string _englishName;
/// <summary>
/// 英文名称
/// </summary>
public string EnglishName
{
get { return _englishName; }
set { _englishName = value; }
}
/// <summary>
/// 单位信息Id
/// </summary>
public int Id
{
get { return id; }
set { id = value; }
}
/// <summary>
/// 单位信息代码
/// </summary>
public string Code
{
get { return code.Trim(); }
set { code = value; }
}
/// <summary>
/// 单位信息中文名称
/// </summary>
public string ChineseName
{
get { return Detail.Trim(); }
set { Detail = value; }
}
/// <summary>
/// 单位信息项号
/// </summary>
public string Xs
{
get { return xs.Trim(); }
set { xs = value; }
}
/// <summary>
/// 单位信息汇率
/// </summary>
public string Rate
{
get { return rate.Trim(); }
set { rate = value; }
}
/// <summary>
/// 是否重量单位
/// </summary>
/// <remarks> 0表示不是;1表示是 </remarks>
public string Flag
{
get { return flag.Trim(); }
set { flag = value; }
}
/// <summary>
/// 是否可以使用小数
/// </summary>
/// <remarks> 0表示不可以;1表示可以 </remarks>
public int IsDecimal
{
get { return decFlag; }
set { decFlag = value; }
}
/// <summary>
/// 根据id比较是否相等(重载)
/// </summary>
/// <param name="obj"> 待比较对象 </param>
/// <returns> true:相等;false:不相等 </returns>
public override bool Equals(Object obj)
{
// return base.Equals(obj);
if ( null == obj) return false ;
Unit u = obj as Unit;
if ( this .Id == u.Id
// && this.Code == u.Code
// && this.IsDecimal == u.IsDecimal
// && this.ChineseName == u.ChineseName
// && this.EnglishName == u.EnglishName
)
return true ;
else
return false ;
}
/// <summary>
/// 重载 ==符号
/// </summary>
/// <param name="srcObj1"> 比较对象1 </param>
/// <param name="detObj2"> 比较对象2 </param>
/// <returns> true:相等;false:不相等 </returns>
public static bool operator == (Unit srcObj1, Unit detObj2)
{
if ( null == ( object )srcObj1 && null == ( object )detObj2)
return true ;
if ( null == ( object )srcObj1 || null == ( object )detObj2)
return false ;
else
return srcObj1.Equals(detObj2);
}
/// <summary>
/// 重载 !=符号
/// </summary>
/// <param name="srcObj1"> 比较对象1 </param>
/// <param name="detObj2"> 比较对象2 </param>
/// <returns> true:不相等;false:相等 </returns>
public static bool operator != (Unit srcObj1, Unit detObj2)
{
if ( null == ( object )srcObj1 && null == ( object )detObj2)
return false ;
if ( null == ( object )srcObj1 || null == ( object )detObj2)
return true ;
else
return ! srcObj1.Equals(detObj2);
}
/// <summary>
/// 重载哈希函数
/// </summary>
/// <returns> 单位id </returns>
public override int GetHashCode()
{
return ( int ) this .Id;
}
#endregion UnitEntity
}
}