摘要

上一节对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对象二级缓存下的更多相关文章

  1. NHibernate系列文章十八:NHibernate关系之一对多(附程序下载)

    摘要 这篇文章介绍NHibernate最实用的内容:关系映射. NHibernate的关系映射方式有三种: Set:无序对象集合,集合中每一个元素不能重复. List:有序对象集合,集合中的元素可以重 ...

  2. NHibernate系列文章十五:NHibernate组件

    摘要 前面文章介绍了NHibernate对简单.net数据类型的映射对照表.NHibernate也可以映射复杂数据类型,这里介绍通过组件映射NHibernate值对象. 1. NHibernate引用 ...

  3. NHibernate系列文章十六:使用程序集管理NHibernate项目(附程序下载)

    摘要 在实际的项目中,经常是将NHibernate的实体关系映射类做成独立的工程(assembly dll),只对外提供Session调用的接口.这个程序集作为数据访问层,可以被上面的多个工程(ASP ...

  4. NHibernate系列文章十二:Load/Get方法

    摘要 NHibernate提供两个方法按主键值查找对象:Load/Get. 1. Load/Get方法的区别 Load: Load方法可以对查询进行优化. Load方法实际得到一proxy对象,并不立 ...

  5. NHibernate系列文章十四:NHibernate事务

    摘要 NHibernate实现事务机制非常简单,调用ISession.BeginTransaction()开启一个事务对象ITransaction,使用ITransaction.Commit()提交事 ...

  6. NHibernate系列文章十九:NHibernate关系之多对多关系(附程序下载)

    摘要 NHibernate的多对多关系映射由many-to-many定义. 从这里下载本文的代码NHibernate Demo 1.修改数据库 添加Product表 添加ProductOrder表 数 ...

  7. NHibernate系列文章目录

    第一章:NHibernate基础 NHibernate介绍 第一个NHibernate工程 简单的增删改查询 运行时监控 NHibernate配置 数据类型映射 Get/Load方法 NHiberna ...

  8. CRL快速开发框架系列教程十(导出对象结构)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  9. NHibernate系列文章九:NHibernate对象二级缓存上

    摘要 NHibernate的二级缓存由SessionFactory管理,由所有Session共享. NHibernate缓存读取顺序: 首先从一级缓存中读取,如果一级缓存对象存在,则读取一级缓存对象并 ...

随机推荐

  1. SCC(强连通分量)

    1.定义: 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(SC---strongly connected). 有向图中的极大强连通子图,成为强连通分量(SCC---strongly ...

  2. Boundaries

    Using Third-Party Code There is a natural tension between the provider of an interface and the user ...

  3. Caffe 源碼閱讀(三) caffe.cpp

    补:主要函数运行顺序: main>>GetBrewFunction>>train>>Solve 從main函數說起: 1.gflags庫中爲main函數設置usag ...

  4. 来自HeroKu的HTTP API 设计指南(中文版)

    原文转自:http://get.jobdeer.com/343.get 来自HeroKu的HTTP API 设计指南(中文版) 翻译 by @Easy 简介 本指南中文翻译者为 @Easy ,他是国内 ...

  5. Mongodb在NUMA机器上的优化

    10gen在mongodb的部署指南上,提到了在NUMA机器上,mongodb可能会出现问题,参见:http://docs.mongodb.org/manual/administration/prod ...

  6. H5版俄罗斯方块(3)---游戏的AI算法

    前言: 算是"long long ago"的事了, 某著名互联网公司在我校举行了一次"lengend code"的比赛, 其中有一题就是"智能俄罗斯方 ...

  7. Node.js高级编程读书笔记 - 2 文件和进程处理

    Outline 3 文件.进程.流和网络 3.1 查询和读写文件 3.2 创建和控制外部进程 3.3 读写数据流 3 文件.进程.流和网络 3.1 查询和读写文件 path 从Node 0.8起,pa ...

  8. C++宽窄字符串转换

    首先,贴出我给出的解决方案: http://files.cnblogs.com/xuejianhui/utils.rar   再则,贴出网上最常见的例子: #include <string> ...

  9. 配置recovery_min_apply_delay后重启standby节点报错:psql: FATAL: the database system is starting up

    环境: pg版本:PostgreSQL 9.4.4 on x86_64 系统版本:CentOS release 6.6 linux内核版本:2.6.32-504.8.1.el6.x86_64 今天测试 ...

  10. 转-利用Oracle审计功能来监测试环境的变化

    http://blog.csdn.net/luowangjun/article/details/5627102利用Oracle审计功能来监测试环境的变化 做过测试的人都应该会碰到这样的情况:测试发现的 ...