NHibernate系列文章十:NHibernate对象二级缓存下
摘要
上一节对NHibernate二级缓存做了简单介绍,NHibernate二级缓存是由SessionFactory管理的,所有Session共享。这一节介绍二级缓存其他两个方面:二级缓存查询和二级缓存管理。
1. NHibernate二级缓存查询
NHibernate二级缓存查询是指NHibernate将查询记录的集合放到二级缓存中,之后每次查询都可以从二级缓存中拿查询记录信息。
二级缓存使用步骤:
1)在hibernate.cfg.xml文件中,使用cache.use_query_cache定义使用二级缓存查询:<property name="cache.use_query_cache">true</property>
2)在代码中显示地使用IQuery.SetCacheable(true)方法,第一次使用这个方法时,将查询条件和查询结果组成一个字典对象放入二级缓存中,字典的键是查询条件,值是查询结果记录集合。在第二次使用同样查询条件查询时再次调用这个方法,NHibernate直接从二级缓存中读取。如果查询结果记录集合在第一次调用SetCacheable后有变化(添加、修改、删除),则会清空二级缓存中的字典对象,第二次查询从数据库查询。
二级缓存查询有多种定义方式:
1)显示启用缓存查询
只使用IQuery.SetCacheable(true)方法。
程序演示
修改hibernate.cfg.xml文件,添加<property name="cache.use_query_cache">true</property>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.connection_string_name">default</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
<property name="cache.provider_class">NHibernate.Cache.HashtableCacheProvider</property>
<property name="cache.use_second_level_cache">true</property>
<property name="cache.use_query_cache">true</property>
<mapping assembly="NHibernateDemoApp"/>
<class-cache class="NHibernateDemoApp.Customer,NHibernateDemoApp" usage="read-write"/>
</session-factory>
</hibernate-configuration>
修改Main函数
static void Main(string[] args)
{
HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
.SetCacheable(true)
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
.SetCacheable(true)
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} Console.WriteLine("Completed");
Console.ReadLine();
}
打开NHibernateProfile,执行程序,监控结果:

第一次查询后将结果存入二级缓存,第二次查询直接从二级缓存中读取。
2)指定命名缓存区域
在代码中显示调用session.SetCacheRegion方法给二级缓存结果一个强命名。
程序演示
修改Main函数
static void Main(string[] args)
{
HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
.SetCacheable(true)
.SetCacheRegion("customer_chache")
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
.SetCacheable(true)
.SetCacheRegion("customer_chache")
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} Console.WriteLine("Completed");
Console.ReadLine();
}
清空NHibernateProfile监控记录,执行程序,得到结果

3)命名查询
在实体关系映射配置文件hibernate.cfg.xml中,定义二级缓存的命名查询。
<query cacheable="true" cache-mode="normal" name="自定义名称">
Hibernate Query Language查询字符串
</query>
cache-mode一般使用normal(默认方式),从二级缓存中读写。
cache-mode有五个枚举值
- Ignore:不使用二级缓存
- Put:只向二级缓存写数据
- Get:只向二级缓存读数据
- Normal:向二级缓存读和写数据
- Refresh:每次强制刷新二级缓存
程序演示
修改Customer.hbm.xml文件
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateDemoApp" namespace="NHibernateDemoApp">
<class name="Customer" table="Customer">
<id name="Id">
<generator class="native"/>
</id>
<property name="FirstName" not-null="true"/>
<property name="LastName" not-null ="true"/>
<property name="AverageRating"/>
<property name="Points"/>
<property name="HasGoldStatus"/>
<property name="MemberSince"/>
<property name="CreditRating" type="CustomerCreditRating"/>
<property name="Street"/>
<property name="City"/>
<property name="Province"/>
<property name="Country"/>
</class>
<query cacheable="true" cache-mode="normal" name="select_customer">
from Customer
</query>
</hibernate-mapping>
修改Main函数
static void Main(string[] args)
{
HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.GetNamedQuery("select_customer")
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.GetNamedQuery("select_customer")
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} Console.WriteLine("Completed");
Console.ReadLine();
}
清空Profile,执行程序得到结果

2. NHibernate二级缓存管理
NHibernate二级缓存由SessionFactory管理,SessionFactory提供了多个删除二级缓存内容的方法。
- Evict:从二级缓存中删除类实例
- EvictEntity:从二级缓存中删除指定实例
- EvictCollection:从二级缓存中删除集合
- EvictQueries:从二级缓存中删除查询
程序演示
修改Main函数
static void Main(string[] args)
{
HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); using (var session = SessionFactory.OpenSession())
{
var customer = session.Get<Customer>();
}
SessionFactory.Evict(typeof(Customer));
using (var session = SessionFactory.OpenSession())
{
var customer = session.Get<Customer>();
} Console.WriteLine("Completed");
Console.ReadLine();
}
清空NHibernateProfile的Session,执行程序得到结果

也可以强制调用session.SetCacheMode(CacheMode.Refresh),刷新二级缓存内容,第二个session查询时,session重新查询数据库。
程序演示
修改Main函数
static void Main(string[] args)
{
HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
.SetCacheable(true)
.SetCacheRegion("customer_chache")
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
.SetCacheable(true)
.SetCacheRegion("customer_chache")
.SetCacheMode(CacheMode.Refresh)
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} Console.WriteLine("Completed");
Console.ReadLine();
}
执行结果,第二次强制查询数据库

NHibernate系列文章十:NHibernate对象二级缓存下的更多相关文章
- NHibernate系列文章十八:NHibernate关系之一对多(附程序下载)
摘要 这篇文章介绍NHibernate最实用的内容:关系映射. NHibernate的关系映射方式有三种: Set:无序对象集合,集合中每一个元素不能重复. List:有序对象集合,集合中的元素可以重 ...
- NHibernate系列文章十五:NHibernate组件
摘要 前面文章介绍了NHibernate对简单.net数据类型的映射对照表.NHibernate也可以映射复杂数据类型,这里介绍通过组件映射NHibernate值对象. 1. NHibernate引用 ...
- NHibernate系列文章十六:使用程序集管理NHibernate项目(附程序下载)
摘要 在实际的项目中,经常是将NHibernate的实体关系映射类做成独立的工程(assembly dll),只对外提供Session调用的接口.这个程序集作为数据访问层,可以被上面的多个工程(ASP ...
- NHibernate系列文章十二:Load/Get方法
摘要 NHibernate提供两个方法按主键值查找对象:Load/Get. 1. Load/Get方法的区别 Load: Load方法可以对查询进行优化. Load方法实际得到一proxy对象,并不立 ...
- NHibernate系列文章十四:NHibernate事务
摘要 NHibernate实现事务机制非常简单,调用ISession.BeginTransaction()开启一个事务对象ITransaction,使用ITransaction.Commit()提交事 ...
- NHibernate系列文章十九:NHibernate关系之多对多关系(附程序下载)
摘要 NHibernate的多对多关系映射由many-to-many定义. 从这里下载本文的代码NHibernate Demo 1.修改数据库 添加Product表 添加ProductOrder表 数 ...
- NHibernate系列文章目录
第一章:NHibernate基础 NHibernate介绍 第一个NHibernate工程 简单的增删改查询 运行时监控 NHibernate配置 数据类型映射 Get/Load方法 NHiberna ...
- CRL快速开发框架系列教程十(导出对象结构)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- NHibernate系列文章九:NHibernate对象二级缓存上
摘要 NHibernate的二级缓存由SessionFactory管理,由所有Session共享. NHibernate缓存读取顺序: 首先从一级缓存中读取,如果一级缓存对象存在,则读取一级缓存对象并 ...
随机推荐
- 百度之星热身赛-1001(dfs拓扑排序)
题意:作为年度优秀魔法学员的奖赏,哈利得到了一台具有魔力的计算机.这台计算机一旦开始处理某个任务,就会一直处理到这个任务结束为止(所以你可以认为它是单线程的).有一天,这台计算机得到了n个任务要处理, ...
- 第三个Sprint冲刺第三天
讨论地点:宿舍 讨论成员:邵家文.李新.朱浩龙.陈俊金 讨论问题:增强了界面的效果,改善了视角
- git-quick-start 动画讲解Git命令行
来源:http://git.oschina.net/wzw/git-quick-start#git-quick-start git-quick-start 这是一个git的快速入门项目,使用一些gif ...
- 2016年中国大学生程序设计竞赛(合肥)-重现赛1009 HDU 5969
最大的位或 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- 重写ScrollView 解决ScrollView嵌套viewpager事件冲突
import android.content.Context; import android.util.AttributeSet; import android.view.GestureDetecto ...
- Web存储(Web Storage)的浏览器支持情况
所有很酷的功能特征的出现最关键的就是浏览器的支持情况,幸运的是,所有的现代浏览器都支持HTML5 Web存储(Web Storage),从IE8开始也支持它.HTML5 Web存储(Web Stora ...
- Bean的定义及作用域的注解实现
1. Classpath扫描与组件管理 从Spring3.0开始,Spring JavaConfig项目提供了很多特性,包括使用java而不是XML定义bean. 比如@configuration, ...
- [原创]cocos2d-x研习录-第二阶 基本框架
了解完Cocos2D-x的基本概念和概念类之后,是不是有一种蠢蠢欲动的冲动,想要探究Cocos2D-x是如何完成这一切的.接着我将通过对Cocos2D-x自代的HelloCpp项目进行分析,初步了解C ...
- js 日期按年月日加减
<script> function isleapyear(year) { if(parseInt(year)%4==0 && parseInt(year)%100!=0)r ...
- Jocket
https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/diagnosTOC.html https://blo ...