学用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配置文件。
<?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>

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" />

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();//
        }

    }

}


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

    }

}


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);

        }

    }

}


posted @ 2005-10-21 14:10  chenjunbiao  阅读(210)  评论(0编辑  收藏  举报