学用NHibernate(一)
场景:
使用Nunit测试一个使用NHibernate的项目,被测试的项目为Job.Personal.Core,测试项目为Job.Personal.Tests。
配置:
1、在主项目中添加对NHibernate.dll的引用,这样同时会关联到Castle.DynamicProxy.dll HashCodeProvider.dll Iesi.Collections.dll 如果需要记录异常日志的则再引用log4net.dll
2、在测试项目中添加对NHibernate.dll的引用。
3、因为测试项目是使用Nunit进行测试,同时这是一个组件项目,所以配置文件要存放在bin/Debug中,命名为:Job.Personal.Tests.dll.config
4、为定位hbm.xml文件,把对该xml文件的生成操作修改为嵌入的资源。
5、编辑Job.Personal.Tests.dll.config配置文件。
6、编辑MyJob.hbm.xml
7、如果使用编辑hbm.xml时使用智能感知,则拷入nhibernate-configuration-2.0.xsd nhibernate-generic.xsd nhibernate-mapping-2.0.xsd文件到hbm.xml所在目录。
8、对于由hbm.xml生成业务对象的操作,则能通过NHibernateContrib,这个在以后的随笔中讲解。现在我们就有了一个对应于hbm.xml的业务对象了。
9、为操作的封装性,这里我提取了Cuyahoga项目对Session的操作,如下:
SessionFactory.cs
CoreRepository.cs
8、在Job.Personal.Tests项目中添加ProxyTest测试类。
使用Nunit测试一个使用NHibernate的项目,被测试的项目为Job.Personal.Core,测试项目为Job.Personal.Tests。
配置:
1、在主项目中添加对NHibernate.dll的引用,这样同时会关联到Castle.DynamicProxy.dll HashCodeProvider.dll Iesi.Collections.dll 如果需要记录异常日志的则再引用log4net.dll
2、在测试项目中添加对NHibernate.dll的引用。
3、因为测试项目是使用Nunit进行测试,同时这是一个组件项目,所以配置文件要存放在bin/Debug中,命名为:Job.Personal.Tests.dll.config
4、为定位hbm.xml文件,把对该xml文件的生成操作修改为嵌入的资源。
5、编辑Job.Personal.Tests.dll.config配置文件。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.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=(local); database=NHBDemo; uid=sa; pwd=007520;" />
</nhibernate>
</configuration>
<configuration>
<configSections>
<section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.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=(local); database=NHBDemo; uid=sa; pwd=007520;" />
</nhibernate>
</configuration>
6、编辑MyJob.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="Job.Personal.Core.Domain.MyJob, Job.Personal.Core" table="Job_Job">
<id name="ID" column="ID" type="Int32" unsaved-value="-1">
<generator class="native" />
</id>
<property name="Guid" type="Guid" column="Guid" />
<property name="EnterpriseGuid" type="Guid" column="EnterpriseGuid" />
<property name="Name" type="String(50)" column="Name" />
<property name="Description" type="String(4000)" column="Description" />
</class>
</hibernate-mapping>
注意:主键的类名必须为ID,如果主键是由数据库自动生成的,则使用<generator class="native" />声明,而不是用<generator class="assigned" /><hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="Job.Personal.Core.Domain.MyJob, Job.Personal.Core" table="Job_Job">
<id name="ID" column="ID" type="Int32" unsaved-value="-1">
<generator class="native" />
</id>
<property name="Guid" type="Guid" column="Guid" />
<property name="EnterpriseGuid" type="Guid" column="EnterpriseGuid" />
<property name="Name" type="String(50)" column="Name" />
<property name="Description" type="String(4000)" column="Description" />
</class>
</hibernate-mapping>
7、如果使用编辑hbm.xml时使用智能感知,则拷入nhibernate-configuration-2.0.xsd nhibernate-generic.xsd nhibernate-mapping-2.0.xsd文件到hbm.xml所在目录。
8、对于由hbm.xml生成业务对象的操作,则能通过NHibernateContrib,这个在以后的随笔中讲解。现在我们就有了一个对应于hbm.xml的业务对象了。
9、为操作的封装性,这里我提取了Cuyahoga项目对Session的操作,如下:
SessionFactory.cs
using System;
using System.Reflection;
using NHibernate;
using NHibernate.Cfg;
namespace Job.Personal.Core.Service
{
/// <summary>
/// SessionFactory 提供 NHibernate sessions
/// </summary>
public class SessionFactory
{
private static SessionFactory _sessionFactory = new SessionFactory();
private Configuration _nhibernateConfiguration;
private ISessionFactory _nhibernateFactory;
private bool _classesAdded = false;
protected SessionFactory()
{
RegisterCoreClasses();
}
public static SessionFactory GetInstance()
{
return _sessionFactory;
}
/// <summary>
/// 返回当前的NHibernate ISessionFactory
/// </summary>
public ISessionFactory GetNHibernateFactory()
{
return this._nhibernateFactory;
}
/// <summary>
/// 获取一个新的NHibernate session
/// </summary>
public ISession GetSession()
{
return this._nhibernateFactory.OpenSession();
}
/// <summary>
/// 添加一个类到NHibernate mappings 如果类已经被映射,则什么也不做
/// </summary>
public void RegisterPersistentClass(Type type)
{
if (this._nhibernateConfiguration.GetClassMapping(type) == null)
{
// Class isn't mapped yet, so do it now.
this._nhibernateConfiguration.AddClass(type);
this._classesAdded = true;
}
}
/// <summary>
/// 重新构建一个NHibernate ISessionFactory,在注册一个新类后使用它。
/// </summary>
public bool Rebuild()
{
// Rebuild NHibernate SessionFactory to activate the new mapping.
if (this._classesAdded)
{
this._nhibernateFactory = this._nhibernateConfiguration.BuildSessionFactory();
this._classesAdded = false;
return true;
}
else
{
return false;
}
}
private void RegisterCoreClasses()
{
Configuration config = new Configuration();
this._nhibernateConfiguration = config.AddAssembly(this.GetType().Assembly); //传入本组件Job.Personal.Core
this._nhibernateFactory = this._nhibernateConfiguration.BuildSessionFactory();//
}
}
}
using System.Reflection;
using NHibernate;
using NHibernate.Cfg;
namespace Job.Personal.Core.Service
{
/// <summary>
/// SessionFactory 提供 NHibernate sessions
/// </summary>
public class SessionFactory
{
private static SessionFactory _sessionFactory = new SessionFactory();
private Configuration _nhibernateConfiguration;
private ISessionFactory _nhibernateFactory;
private bool _classesAdded = false;
protected SessionFactory()
{
RegisterCoreClasses();
}
public static SessionFactory GetInstance()
{
return _sessionFactory;
}
/// <summary>
/// 返回当前的NHibernate ISessionFactory
/// </summary>
public ISessionFactory GetNHibernateFactory()
{
return this._nhibernateFactory;
}
/// <summary>
/// 获取一个新的NHibernate session
/// </summary>
public ISession GetSession()
{
return this._nhibernateFactory.OpenSession();
}
/// <summary>
/// 添加一个类到NHibernate mappings 如果类已经被映射,则什么也不做
/// </summary>
public void RegisterPersistentClass(Type type)
{
if (this._nhibernateConfiguration.GetClassMapping(type) == null)
{
// Class isn't mapped yet, so do it now.
this._nhibernateConfiguration.AddClass(type);
this._classesAdded = true;
}
}
/// <summary>
/// 重新构建一个NHibernate ISessionFactory,在注册一个新类后使用它。
/// </summary>
public bool Rebuild()
{
// Rebuild NHibernate SessionFactory to activate the new mapping.
if (this._classesAdded)
{
this._nhibernateFactory = this._nhibernateConfiguration.BuildSessionFactory();
this._classesAdded = false;
return true;
}
else
{
return false;
}
}
private void RegisterCoreClasses()
{
Configuration config = new Configuration();
this._nhibernateConfiguration = config.AddAssembly(this.GetType().Assembly); //传入本组件Job.Personal.Core
this._nhibernateFactory = this._nhibernateConfiguration.BuildSessionFactory();//
}
}
}
CoreRepository.cs
using System;
using System.Collections;
using System.Reflection;
using log4net;
using NHibernate;
using NHibernate.Expression;
using Job.Personal.Core.Domain;
namespace Job.Personal.Core.Service
{
/// <summary>
/// CoreRepository 的摘要说明。
/// </summary>
public class CoreRepository
{
private static readonly ILog log = LogManager.GetLogger(typeof(CoreRepository));
private ISessionFactory _factory;
private ISession _activeSession;
/// <summary>
/// 获取当前活跃的NHibernate session
/// </summary>
public ISession ActiveSession
{
get { return _activeSession; }
}
public CoreRepository() : this(false)
{
}
/// <summary>
/// 为核心对象创建一个库贮藏
/// </summary>
/// <param name="openSession">指示CoreRepository是否应该打开一个session并保存到内存中</param>
public CoreRepository(bool openSession)
{
this._factory = SessionFactory.GetInstance().GetNHibernateFactory();
if (openSession)
{
this._activeSession = this._factory.OpenSession();
}
}
/// <summary>
/// 打开一个NHibernate session
/// </summary>
public void OpenSession()
{
if (this._activeSession == null || ! this._activeSession.IsOpen)
{
this._activeSession = this._factory.OpenSession();
}
else
{
throw new InvalidOperationException("The repository already has an open session");
}
}
/// <summary>
/// Flushes the current active NHibernate session.
/// </summary>
public void FlushSession()
{
if (this._activeSession != null && this._activeSession.IsOpen)
{
this._activeSession.Flush();
}
}
/// <summary>
/// Close the active NHibernate session
/// </summary>
public void CloseSession()
{
if (this._activeSession != null)
{
if (this._activeSession.IsOpen)
{
this._activeSession.Close();
}
this._activeSession.Dispose();
}
}
Generic methods
}
}
using System.Collections;
using System.Reflection;
using log4net;
using NHibernate;
using NHibernate.Expression;
using Job.Personal.Core.Domain;
namespace Job.Personal.Core.Service
{
/// <summary>
/// CoreRepository 的摘要说明。
/// </summary>
public class CoreRepository
{
private static readonly ILog log = LogManager.GetLogger(typeof(CoreRepository));
private ISessionFactory _factory;
private ISession _activeSession;
/// <summary>
/// 获取当前活跃的NHibernate session
/// </summary>
public ISession ActiveSession
{
get { return _activeSession; }
}
public CoreRepository() : this(false)
{
}
/// <summary>
/// 为核心对象创建一个库贮藏
/// </summary>
/// <param name="openSession">指示CoreRepository是否应该打开一个session并保存到内存中</param>
public CoreRepository(bool openSession)
{
this._factory = SessionFactory.GetInstance().GetNHibernateFactory();
if (openSession)
{
this._activeSession = this._factory.OpenSession();
}
}
/// <summary>
/// 打开一个NHibernate session
/// </summary>
public void OpenSession()
{
if (this._activeSession == null || ! this._activeSession.IsOpen)
{
this._activeSession = this._factory.OpenSession();
}
else
{
throw new InvalidOperationException("The repository already has an open session");
}
}
/// <summary>
/// Flushes the current active NHibernate session.
/// </summary>
public void FlushSession()
{
if (this._activeSession != null && this._activeSession.IsOpen)
{
this._activeSession.Flush();
}
}
/// <summary>
/// Close the active NHibernate session
/// </summary>
public void CloseSession()
{
if (this._activeSession != null)
{
if (this._activeSession.IsOpen)
{
this._activeSession.Close();
}
this._activeSession.Dispose();
}
}
Generic methods
}
}
8、在Job.Personal.Tests项目中添加ProxyTest测试类。
using System;
using NUnit.Framework;
using NHibernate;
using NHibernate.Cfg;
using Job.Personal.Core.Domain;
using Job.Personal.Core.Service;
namespace Job.Personal.Tests
{
[TestFixture]
public class ProxyTest
{
public ProxyTest(){}
[Test]
public void ProxyTestTemplate()
{
CoreRepository cr = new CoreRepository(true);
MyJob job = new MyJob();
job.Guid = Guid.NewGuid();
job.EnterpriseGuid = Guid.NewGuid();
job.Name = "测试";
cr.SaveObject(job);
}
}
}
using NUnit.Framework;
using NHibernate;
using NHibernate.Cfg;
using Job.Personal.Core.Domain;
using Job.Personal.Core.Service;
namespace Job.Personal.Tests
{
[TestFixture]
public class ProxyTest
{
public ProxyTest(){}
[Test]
public void ProxyTestTemplate()
{
CoreRepository cr = new CoreRepository(true);
MyJob job = new MyJob();
job.Guid = Guid.NewGuid();
job.EnterpriseGuid = Guid.NewGuid();
job.Name = "测试";
cr.SaveObject(job);
}
}
}