在Spring.Net中利用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.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节点的时候,可以发现这样的一段代码:
这里的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节点:
<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的一些基本配置:
如何测试使用二级缓存呢?这里写了一个单元测试:
public void EnterpriseDaoTest3()
{
IEnterpriseDao dao = (IEnterpriseDao)applicationContext.GetObject("EnterpriseDao");
ITblEnterprise enterprise = dao.GetInfo(1);
//Assert.IsNull(enterprise);
Console.WriteLine(enterprise.Name);
}
看下如何操作:
/// 企业信息数据访问对象
/// </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上的配置经验:)