由于本人在项目工作中一直致力于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 事务。
二、示例代码
我们看看他们是如何协同工作的,请看下面的代码。
代码示例(未改变数据库中的数据,查询操作):
Configuration的Configure方法,将使用应用程序的配置文件或者hibernate.cfg.xml文件的<hibernate-configuration>节点进行配置,返回值是一个配置好了的Configuration对象的实例。
然后这个Configuration通过BuildSessionFactory方法创建ISessionFactory的实例。
ISessionFactory的实例通过OpenSession打开一个ISession的实例,用这个实例完成数据库的操作,然后关闭它。
如果你的代码中需要事务,只需要把代码稍微修改一下。
代码示例(改变了数据库中的数据,数据的增删改):
我一般在不影响数据的方法(例如:查询)中不包含事务,而影响数据的方法(例如:增删改)使用事务。
由于在本项目中使用了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
}
}