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

        }

    }

}


你可能感兴趣的:(Hibernate)