在Spring.Net中利用NHibernate配置增加二级缓存

先上这样的一段系统配置:

代码
  <!-- NHibernate配置 开始 -->
  
<object id="NHibernateSessionFactory" type="Xino.Spring.DecryptLocalSessionFactoryObject, Xino.Core.Spring">
    
<property name="DbProviderWithDecrypt" ref="DbProvider" />
    
<property name="MappingAssemblies">
      
<list>
        
<value>TestWebServer.Model</value>
      
</list>
    
</property>
    
<property name="HibernateProperties">
      
<dictionary>
        
<entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
        
<entry key="dialect" value="NHibernate.Dialect.MsSql2005Dialect"/>
        
<entry key="connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
        
<entry key="use_outer_join" value="true"/>
        
<entry key="dynamic-update" value="true"/>
        
<entry key="show_sql" value="true"/>
        
<!--<entry key="hbm2ddl.auto" value="update"/>-->
        
<entry key="hibernate.current_session_context_class" value="Spring.Data.NHibernate.SpringSessionContext, Spring.Data.NHibernate21"/>
        
<!--<entry key="proxyfactory.factory_class" value="NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu"/>-->
        
<!-- 启用二级缓存配置 -->
        
<entry key="cache.provider_class" value="NHibernate.Cache.HashtableCacheProvider"/>
        
<entry key="cache.use_second_level_cache" value="false"/>
        
<entry key="cache.use_query_cache" value="true"/>
        
<!--<entry key="cache.provider_class" value="NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache"/>-->
      
</dictionary>
    
</property>
    
<property name="EntityCacheStrategies">
      
<object type="Spring.Util.Properties">
        
<property name="['TestWebServer.Model.TblEnterprise,TestWebServer.Model']" value="read-write"/>
      
</object>
    
</property>
    
<property name="ExposeTransactionAwareSessionFactory" value="true" />
  
</object>
  
<!-- 事务处理策略 - 本地数据库事务 -->
  
<object id="transactionManager"
        type
="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate21">
    
<property name="DbProvider" ref="DbProvider"/>
    
<property name="SessionFactory" ref="NHibernateSessionFactory"/>
  
</object>
  
<!--将id为NHibernateSessionFactory的对象注入到HibernateTemplate中-->
  
<object id="HibernateTemplate" type="Spring.Data.NHibernate.Generic.HibernateTemplate">
    
<property name="SessionFactory" ref="NHibernateSessionFactory" />
    
<property name="TemplateFlushMode" value="Auto" />
    
<property name="CacheQueries" value="true" />
  
</object>
  
<!-- NHibernate配置 结束 -->

可以看到一个HibernateProperties的配置节,这个属性是在Xino.Spring.DecryptLocalSessionFactoryObject, Xino.Core.Spring,这里继承的是Spring.Data.NHibernate.LocalSessionFactoryObject类,这个类主要用来配置SessionFactory各种操作。

当需要启用二级缓存配置时,需要加上

代码
        <entry key="cache.provider_class" value="NHibernate.Cache.HashtableCacheProvider"/>
        
<entry key="cache.use_second_level_cache" value="true"/>
        
<entry key="cache.use_query_cache" value="true"/>
        
<!--<entry key="cache.provider_class" value="NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache"/>-->

其中NHibernate.Cache.HashtableCacheProvider类是NHibernate默认的缓冲处理器,如果你需要使用第三方的缓冲组件可以采用NHibernate官网上的NHibernate Contrib去下载。

例如以上注释的地方。

这里需要注意的地方是

配置EntityCacheStrategies节点的时候,可以发现这样的一段代码:

<property name="['TestWebServer.Model.TblEnterprise,TestWebServer.Model']" value="read-write"/>

这里的name必须加上"['MyProject.ClassName,AssemblyName']"的方式,而不是MyProject.ClassName,AssemblyName,不然会报错。

其中这里的value可以为read-write,read-only,nonstrict-read-write,transactional,分别代表的意思是:

read-only:只读缓存。适用于只读数据,可用于群集中。
read-write:读写缓存。
nonstrict-read-write:非严格读写缓存,不保证缓存与数据库的一致性。
transactional:事务缓存。提供可重复读的事务隔离级别。
然后在对应的TblEnterprise.hbm.xml加上一个cache节点:

代码
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="true" namespace="TestWebServer.Model" assembly="TestWebServer.Model">
    
<class name="TblEnterprise,TestWebServer.Model" table="tbl_Enterprise" lazy="true">
    
<cache usage="read-write"/>
        
<!-- Primary Key(s) -->
        
<id name="Id" column="Id" type="Int32" unsaved-value="0">
            
<generator class="native"/>
        
</id>
        
        
<!-- Properties -->
        
<property column="Code" type="String" name="Code" length="32" />
        
<property column="Name" type="String" name="Name" length="50" />
        
<property column="TradeId" type="Int32" name="TradeId" />
        
<property column="Lawyer" type="String" name="Lawyer" length="20" />
        
<property column="Licence" type="String" name="Licence" length="30" />
        
<property column="CreateTime" type="DateTime" name="CreateTime" />
        
<property column="Status" type="Int32" name="Status" />
        
    
</class>
</hibernate-mapping>

这样就完成了Spring.Net+Nhibernate的一些基本配置:

如何测试使用二级缓存呢?这里写了一个单元测试:

代码
        [Test]
        
public void EnterpriseDaoTest3()
        {
            IEnterpriseDao dao 
= (IEnterpriseDao)applicationContext.GetObject("EnterpriseDao");
            ITblEnterprise enterprise 
= dao.GetInfo(1);
            
//Assert.IsNull(enterprise);

            Console.WriteLine(enterprise.Name);
        }

看下如何操作:

代码
    /// <summary>
    
/// 企业信息数据访问对象
    
/// </summary>
    public class EnterpriseDao : NHibernateDao<TblEnterprise, ITblEnterprise>, IEnterpriseDao
    {
        
public ITblEnterprise GetInfo(int id)
        {
            ITblEnterprise entity;
            
using (Session)
            {
                entity 
= GetInfoById(id);
            }
            
//清除Session
            Clear();
            
using (Session)
            {
                entity
= GetInfoById(id);
            }
            
return entity;
        }
        
// ...
    }

然后在没缓存的情况(<entry key="cache.use_second_level_cache" value="false"/>)下执行下结果

在开启缓存的情况下执行结果

说明说,即使在不同的Session下面,查询操作已经做了二级缓存,对了,什么是一级缓存呢?一级缓存就是在同一个Session下面,NHibernate利用内置的缓存策略进行缓存,但是不同的Session是不进行缓存的。

以上是总结的一些关于Spring.Net和Nhibernate上的配置经验:)

posted @ 2010-12-17 12:01  Leepy  阅读(3737)  评论(5编辑  收藏  举报