在spring.net中集成nHibernate可以获得许多值得称道的特性。比如:基于元标记(meta Attributes)的事务支持、对物理数据库的抽象、对数据层进行切面式拦截。

  好处是不少,但首先要学会配置。为了这个集成的环境,建立一个配置文件 applicationContext.xml :


    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd"
>
  
<!--spring集合nHibernate-->
  
<object id="DbProvider" type="woodigg.DAO.SQLProvider,woodigg.DAO">
    
<property name="ConnectionString"
          value
="Server=(local);database=Music;User Id=sa;Password=******;Trusted_Connection=False" />
  
</object>

  
<!--session工厂-->
  
<object id="SessionFactory"
          type
="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate12">
    
<property name="DbProvider" ref="DbProvider" />
    
<property name="MappingAssemblies">
      
<list>
        
<value>woodigg.DAO</value>
        
<value>woodigg.model</value>
      
</list>
    
</property>
    
<property name="HibernateProperties">
      
<dictionary>
        
<entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
        
<entry key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect" />
        
<entry key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
        
<entry key="show_sql" value="false" />
        
<entry key="hibernate.current_session_context_class" value="Spring.Data.NHibernate.SpringSessionContext, Spring.Data.NHibernate12"/>
        
<entry key="hibernate.query.factory_class" value="NHibernate.Hql.Classic.ClassicQueryTranslatorFactory" />
        
<entry key="hibernate.cache.provider_class" value="NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache" />
        
<entry key="relativeExpiration" value="5" />
      
</dictionary>
    
</property>
  
</object>
  
<!--事务管理器-->
  
<object id="HibernateTransactionManager"
          type
="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate12">
    
<property name="DbProvider" ref="DbProvider" />
    
<property name="SessionFactory" ref="SessionFactory" />
  
</object>
  
<!--事务拦截器-->
  
<object id="TransactionInterceptor"
          type
="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
    
<property name="TransactionManager" ref="HibernateTransactionManager" />
    
<property name="TransactionAttributeSource">
      
<object type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data" />
    
</property>
  
</object>
  
<!--HibernateTemplate-->
  
<object id="HibernateTemplate"
          type
="Spring.Data.NHibernate.HibernateTemplate,Spring.Data.NHibernate12">
    
<property name="SessionFactory" ref="SessionFactory" />
  
</object>
  
<!--Dao代理模板-->
  
<object id="DaoTemplate" type="woodigg.DAO.DaoTemplate, woodigg.DAO">
    
<property name="SessionFactory" ref="SessionFactory" />
  
</object>
  
</objects>

  OK,这里有几处需要说明:
   一、woodigg.DAO.SQLProvider 是一个数据结构类,用以描述物理数据库的相关信息,诸如连接串、元数据信息等。这里其实就用到了连接串,在配置中植入位置、帐号信息等就能连接到数据源。这个SQLProvider类结构如下:

 woodigg.DAO
{
    public class SQLProvider : IDbProvider
    {
        
#region IDbProvider 成员
        
private string _connectionString = "";
        
public string ConnectionString
        {
            
get
            {
                
return this._connectionString;
            }
            
set
            {
                
this._connectionString = value;
            }
        }

        
public IDbCommand CreateCommand()
        {
            
return null;
        }

        
public object CreateCommandBuilder()
        {
            
return null;
        }

        
public IDbConnection CreateConnection()
        {
            
return null;
        }

        
public IDbDataAdapter CreateDataAdapter()
        {
            
return null;
        }

        
public IDbDataParameter CreateParameter()
        {
            
return null;
        }

        
public string CreateParameterName(string name)
        {
            
return null;
        }

        
public string CreateParameterNameForCollection(string name)
        {
            
return null;
        }

        
public IDbMetadata DbMetadata
        {
            
get
            {
                
return null;
            }
        }

        
public string ExtractError(Exception e)
        {
            
return null;
        }

        
public bool IsDataAccessException(Exception e)
        {
            
return false;
        }

        
#endregion
    }

}

 二、在SessionFactory配置中,指明需要环境映射的程序集名称,通俗说法是:哪些层会在集成环境中,被直接引用?这里以示例项目来说是:woodigg.DAO和woodigg.Model,分别为实体(上一节中生成的一堆.cs实体)层,和数据映射文件(被嵌入在项目中的hbm.xml文件)所在的数据访问层。
三、HibernateProperties节中,可以指定调试时是否显示生成的sql语句。同时,能配置缓存事宜:此处用到的是NHibernate.Caches.SysCache。
四、配置HibernateTemplate。nHibernate的模板,既nHibernate项目已经为开发者写好了一套通用的方法,能便捷的操作数据库,此处将SessionFactory植入引用即能让它工作起来。(并不是所有的复杂SQL,它都能做到,不能完成的功能,我们得自己写,这个马上会交待)。
五、DaoTemplate,就是我自己写的一个基于以上配置的复杂模板,能完成诸如Distinct,top,调用分页存储过程等一干复杂SQL功能,抛出来做点贡献吧:

 

.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板using System;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
using System.Collections;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
using System.Collections.Generic;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
using System.Text;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
using System.Data;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
using System.Reflection;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
using NHibernate;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
using NHibernate.Cfg;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
using NHibernate.Engine;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
using NHibernate.Criterion;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
using Spring.Dao;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
using Spring.Data.NHibernate.Support;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
using woodigg.model;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
using log4net;
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
.net企业级架构实战之4——Spring.net下的nHibernate数据访问模板
namespace woodigg.DAO


这是内个配合使用的sql server分页存储过程,原来从网上摘的,动手改过两次以适配distinct取数据:

 

+ @PrimaryKey + "] from " + @tblName + " where " + @strWhere + " " 
+ @strOrder + ")  and " + @strWhere + " " + @strOrder 
end 
end 
print @strSQL
exec (@strSQL)
GO

 

  最后,要让这个环境在程序中生效,得在web.config中加载它:

 


        <sectionGroup name="spring">
            
<section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
            
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
        
</sectionGroup>
        
<section name="SpringOverrideProperty" type="System.Configuration.NameValueSectionHandler"/>
        
<section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
        
<!--log4net-->
        
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
    
</configSections>    
    
<spring>
        
<context>
            
<resource uri="config://spring/objects"/>
            
<resource uri="~/config/applicationContext.xml"/>
            
<resource uri="~/config/business.xml"/>
            
<resource uri="~/config/controllers.xml"/>
            
<resource uri="~/config/pageConfig.xml"/>
            
<resource uri="~/config/serviceConfig.xml"/>
        
</context>
        
<objects xmlns="http://www.springframework.net"/>
    
</spring>

 

  先写到这里吧,博客园的编辑器对机器配置要求不低,粘贴几段代码,界面几乎不能动弹,做罢了。下一回,将介绍怎么应用这个集成的环境。


 

  这里放出一个项目的mini demo:精简版spring.net集成Demo,点击下载

相关文章: