[Nhibernate]二级缓存(一)
2014-11-30 11:33
211 查看
目录
写在前面文档与系列文章
二级缓存
Nhibernate二级缓存提供程序
一个例子
总结
写在前面
上篇文章介绍了nhibernate中一级缓存的相关内容,一级缓存过期时间和ISession对象的生命周期相同,并且不同的Session不能共享缓存,一级缓存也可以成为ISession缓存。那么现在我们就学一下nhibernate中的二级缓存,即ISessionFactory级别缓存,可被所有的ISession所共享。二级缓存是可扩展的,在http://sourceforge.net/projects/nhcontrib/上提供了第三方的Nhibernate二级缓存提供程序。文档与系列文章
[Nhibernate]体系结构[NHibernate]ISessionFactory配置
[NHibernate]持久化类(Persistent Classes)
[NHibernate]O/R Mapping基础
[NHibernate]集合类(Collections)映射
[NHibernate]关联映射
[NHibernate]Parent/Child
[NHibernate]缓存(NHibernate.Caches)
[NHibernate]NHibernate.Tool.hbm2net
[NHibernate]Nullables
[NHibernate]Nhibernate如何映射sqlserver中image字段
[NHibernate]基本配置与测试
[NHibernate]HQL查询
[NHibernate]条件查询Criteria Query
[NHibernate]增删改操作
[NHibernate]事务
[NHibernate]并发控制
[NHibernate]组件之依赖对象
[NHibernate]一对多关系(级联删除,级联添加)
[NHibernate]一对多关系(关联查询)
[NHibernate]多对多关系(关联查询)
[NHibernate]延迟加载
[NHibernate]立即加载
[NHibernate]视图处理
[NHibernate]N+1 Select查询问题分析
[NHibernate]存储过程的使用(一)
[NHibernate]存储过程的使用(二)
[NHibernate]存储过程的使用(三)
[Nhibernate]SchemaExport工具的使用(一)——通过映射文件修改数据表
[Nhibernate]SchemaExport工具的使用(二)——创建表及其约束、存储过程、视图
[Nhibernate]对象状态
[Nhibernate]一级缓存
二级缓存
关于二级缓存的详细可以参考[NHibernate]缓存(NHibernate.Caches)。NHibernate session有一个内部的(一级)缓存,存放着它的实体。这些缓存没有共享,因此session被销毁时它的缓存也被销毁了。NHibernate提供了二级缓存系统;它在SessionFactory级别工作。因此它被同一个SessionFactory产生的session共享。
在NHibernate中,当我们启用NHibernate二级缓存。
使用ISession进行数据操作时,NHibernate首先从内置缓存(一级缓存)中查找是否存在需要的数据,如果内置缓存不存在需要的数据,则查询二级缓存,如果二级缓存中存在所需数据,则直接使用缓存中数据,否则从数据库中查询数据并放入缓存中。
NHibernate本身提供了一个基于Hashtable的HashtableCache缓存,但是功能非常有限而且性能比较差,不适合在大型应用程序使用,我们可以使用第三方缓存提供程序作为NHibernate二级缓存实现。
使用缓存的缺点:
如果缓存策略设置不当,NHibernate不知道其它应用程序对数据库的修改及时更新缓存。因此,建议只对系统经常使用、数据量不大且不会被其它应用程序修改的只读数据(或很少被修改的数据)使用缓存。
Nhibernate二级缓存提供程序
NHibernate提供了NHibernate.Cache.ICacheProvider接口用来支持第三方缓存提供程序实现。开发缓存提供程序时,需要实现该接口作为NHibernate和缓存实现直接的适配器。NHibernate提供了常见的缓存提供程序的内置适配器,这些适配器都实现了NHibernate.Cache.ICacheProvider接口。NHibernate.Cache.ICacheProvider定义如下:
<?xml version="1.0" encoding="utf-8" ?> <!--assembly:程序集,namespace:命名空间--> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Wolfy.Shop.Domain" namespace="Wolfy.Shop.Domain.Entities"> <!--存储过程--> <class name="Wolfy.Shop.Domain.Entities.Customer,Wolfy.Shop.Domain" table="TB_Customer"> <!--二级缓存--> <cache usage="read-write"/> <!--主键--> <id name="CustomerID" type="Guid" unsaved-value="null"> <column name="CustomerID" sql-type="uniqueidentifier" not-null="true" unique="true" /> <generator class="assigned"></generator> </id> <!--版本控制--> <version name="Version" column="Version" type="integer" unsaved-value="0"/> <!--组件 name组件属性名--> <component name="NameAddress" class="Wolfy.Shop.Domain.Entities.Name,Wolfy.Shop.Domain"> <!--Name类中的属性property--> <property name="CustomerName" column ="CustomerName" type="string" length="16" not-null="false" /> <property name ="CustomerAddress" column="CustomerAddress" type="string" length="128" not-null="false" /> </component> <!--一对多关系:一个客户可以有一个或者多个订单--> <!--子实体负责维护关联关系--> <set name="Orders" table="TB_Order" generic="true" inverse="true" cascade="all"> <key column="CustomerID" foreign-key="FK_TB_Order_TB_Customer"></key> <one-to-many class="Wolfy.Shop.Domain.Entities.Order,Wolfy.Shop.Domain"/> </set> <!--存储过程,check参数:none/rowcount/param--> <sql-insert>exec TB_CustomerInsert ?,?,?,?</sql-insert> <!--<sql-update>exec TB_CustomerUpdate ?,?,?,?</sql-update>--> <sql-update>UPDATE TB_CustomerUpdate SET Version=?, [CustomerName]=?,[CustomerAddress]=? WHERE CustomerID=? AND Version=? </sql-update> <!--<sql-delete check="rowcount" >exec TB_CustomerDelete ?</sql-delete>--> <sql-delete>DELETE FROM [TB_Customer] WHERE [CustomerID] = ? and [Version] =?</sql-delete> </class> <!--需要和class节点同一级别--> <sql-query name="ps_Search" > <!--<return class="Wolfy.Shop.Domain.Entities.Customer,Wolfy.Shop.Domain" />--> <return-scalar column="CustomerName" type="String"/> exec ps_Search :CustomerID </sql-query> </hibernate-mapping>
View Code
在不同的Session中查询实体
/// <summary> /// 根据客户id查询 /// </summary> /// <param name="customerID"></param> /// <returns></returns> public Customer GetCustomerById(Guid customerID) { ISession session = NHibernateHelper.GetSession(); return session.Get<Customer>(customerID); } /// <summary> /// 根据客户id查询 /// </summary> /// <param name="customerID"></param> /// <returns></returns> public Customer GetCustomerById2(Guid customerID) { //重置Session ISession session = NHibernateHelper.ResetSession(); return session.Get<Customer>(customerID); }
单元测试
[TestMethod] public void GetCustomerById2Test() { Console.WriteLine("Session1 第一次加载"); Customer c1 = _customerData.GetCustomerById(new Guid("DDF63750-3307-461B-B96A-7FF356540CB8")); Assert.IsNotNull(c1); Console.WriteLine("Session2 第二次加载"); Customer c2 = _customerData.GetCustomerById2(new Guid("DDF63750-3307-461B-B96A-7FF356540CB8")); Assert.IsNotNull(c2); }
在第一次查询数据时,由于一级、二级缓存中都不存在需要的数据,这时NHibernate从数据库中查询数据。第二次读取同一数据,NHibernate首先从内置缓存(一级缓存)中查找是否存在所需要数据,由于不是在同一个ISession中,所以内置ISession缓存中不存在所需数据,NHibernate则查询二级缓存,这时由于第一次查询了这条数据,所以在二级缓存中存在所需数据,则直接使用缓存中数据。(该测试方法与一级缓存中的测试方法相同,为了方便对比,将上篇文章中的图贴在一起进行对比)
一级缓存测试结果
二级缓存测试结果
通过对比,可以发现在单元测试中第二次会话,断言c2不为null通过了测试,说明c2是从缓存中取的。也印证了ISessionFactory级别的二级缓存是可以共享缓存的。
总结
在学习nhibernate过程中难免遇到各种各样的错误,学习的过程也是解决各种异常的过程。关于二级缓存中简单的查询缓存就介绍到这里,下篇文章将介绍二级缓存针对删除,修改的策略及缓存的管理的内容。
参考文章
/article/4592916.html
相关文章推荐
- nhibernate性能之二级缓存篇
- Spring.NET实用技巧1——基于Prevalence下的NHibernate二级缓存使用技巧
- NHibernate之旅(24):探索NHibernate二级缓存(下)
- NHibernate第三方二级缓存bug
- 01-08-02【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider
- NHibernate系列文章十:NHibernate对象二级缓存下
- NHibernate二级缓存攻略
- NHibernate之旅(24):探索NHibernate二级缓存(下)(转)
- nhibernate性能之二级缓存篇
- 设计一套基于NHibernate二级缓存的MongoDB组件(上)
- 在NHibernate中使用memcache二级缓存
- NHibernate二级缓存(第十一篇)
- 下面是在NHibernate中使用memcache二级缓存的详细操作记录。
- 01-08-03【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之查询缓存
- NHibernate之旅(24):探索NHibernate二级缓存(下)
- 01-08-04【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之命名缓存
- NHibernate之旅(23):探索NHibernate二级缓存(上)
- 01-08-03【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之缓存管理
- 在Spring.Net中利用NHibernate配置增加二级缓存
- NHibernate之旅(24):探索NHibernate二级缓存(下)