NHibernate教程(19) —— 一级缓存
本节内容
- 引入
- NHibernate一级缓存介绍
- NHibernate一级缓存管理
- 结语
引入
大家看看上一篇了吗?对象状态。这很容易延伸到NHibernate的缓存。在项目中我们灵活的使用NHibernate的缓存机制。NHibernate性能会大大提高的哦,我们接下来就来探索NHibernate缓存机制吧,这篇我没有准备什么,先来学习下NHibernate一级缓存。
NHibernate一级缓存介绍
NHibernate一级缓存即ISession缓存,ISession缓存属于事务级缓存,是NHibernate内置的。ISession缓存中的数据只在本ISession周期内使用。
ISession实例创建后即可使用ISession缓存。此后,ISession实例操作数据时,首先查询内置缓存,如果ISession缓存中存在相应数据,则直接使用缓存数据。如果不存在,则查询数据库并把其结果存在缓存中。
实例1:查询一次持久化实例
[Test]
public void SessionCacheTest()
{
Customer customer = _transaction.GetCustomerById(1);
}
我们一般就是这样查询一条数据,NHibernate初始化ISession后,ISession缓存中不存在这个数据,这时NHibernate需要从数据库中加载数据。

实例2:一个会话装载两次持久化实例
[Test]
public void SessionCacheTest2()
{
Console.WriteLine("第一次读取持久化实例");
Customer customer1 = _transaction.GetCustomerById(1);
Console.WriteLine("第二次读取持久化实例");
Customer customer2 = _transaction.GetCustomerById(1);
Assert.AreSame(customer1, customer2);
}
第一次加载数据后,持久化实例放入缓存。第二次查询同一个持久化实例时,缓存中已经存在该持久化实例,应用程序将直接从缓存中获取数据,而不必再次从数据库中读取数据,这样同时也提高了查询效率,看看结果:

实例3:分别在两个会话中装载持久化实例
[Test]
public void SessionCacheTest3()
{
using (_session)
{
Console.WriteLine("--Session 1--读取持久化实例");
Customer customer = _transaction.GetCustomerById(1);
Assert.IsTrue(_session.Contains(customer));
}
ResetSession();
using (_session)
{
Console.WriteLine("--Session 2--读取持久化实例");
Customer customer = _transaction.GetCustomerById(1);
Assert.IsTrue(_session.Contains(customer));
}
}
在两个会话中获取同一持久化实例时,两个会话的缓存是独立的,一个会话的数据操作不会影响到另外一个会话。看看输出结果:

从结果我们可以说明虽然这两个会话读取的是同一个实例,但需要两次数据库操作,从而证明了Session缓存不是共享的,一个Session的缓存内容只有在本Session实例范围内可用。
实例4:比较ISession.Get()和ISession.Load()
不会吧,探索缓存比较这个?呵呵,如果你理解了它们的不同,或许你对NHibernate缓存还有一点了解了。开始。
测试1:使用ISession.Get()方法按标识符获取Customer对象,访问标识符,再访问其它属性。
[Test]
public void GetExistingEntityTest()
{
Console.WriteLine("----获取持久化实例----");
Customer customerGet = _session.Get<Customer>(1);
Assert.IsNotNull(customerGet);
Console.WriteLine("------访问这个实例的CustomerId属性------");
Console.WriteLine("这个实例CustomerId属性:{0}", customerGet.CustomerId);
Assert.AreEqual(customerGet.CustomerId, 1);
Console.WriteLine("------访问这个实例的FirstName属性(不是CustomerId)-----");
Console.WriteLine("这个实例的FirstName属性:{0}", customerGet.Name.Firstname);
}
直接看结果:

测试2:使用ISession.Load()方法按标识符获取Customer对象,访问标识符,再访问其它属性。
[Test]
public void LoadExistingEntityTest()
{
Console.WriteLine("----加载持久化实例----");
Customer customerLoad = _session.Load<Customer>(1);
Assert.IsNotNull(customerLoad);
Console.WriteLine("------访问这个实例的CustomerId属性----");
Console.WriteLine("这个实例CustomerId属性:{0}", customerLoad.CustomerId);
Assert.AreEqual(customerLoad.CustomerId, 1);
Console.WriteLine("------访问这个实例的FirstName属性(不是CustomerId)----");
Console.WriteLine("这个实例的FirstName属性:{0}", customerLoad.Name.Firstname);
}
看看结果:

看到不同点了吗?这就是区别,我在测试中发现了这个秘密,使用ISession.Get()方法立即把对象实例保存到缓存中,使用ISession.Load()方法当你需要使用的时候再访问数据库把这个实例保存在缓存中。
NHibernate一级缓存管理
NHibernate为我们默认提供了一级缓存,那么我们想显式地去管理ISession缓存,怎么办呢?ISession接口为我们提供了一些方法来显式管理一级缓存。
ISession.Evict(object):从缓存中删除指定实例。
ISession.Clear():清空缓存。
ISession.Contains(object):检查缓存中是否包含指定实例。
实例分析
我们写一个测试来看看如何显式管理吧:
[Test]
public void SessionCacheManageTest()
{
//1.加载两个实例放入ISession缓存
Customer customer1 = _transaction.GetCustomerById(1);
Customer customer2 = _transaction.GetCustomerById(2);
//2.加载实例后,缓存包含两个实例
Assert.IsTrue(_session.Contains(customer1));
Assert.IsTrue(_session.Contains(customer2));
//3.从缓存中删除Customer1实例
_session.Evict(customer1);
Assert.IsFalse(_session.Contains(customer1));
Assert.IsTrue(_session.Contains(customer2));
//4.清空ISession缓存,实例不和缓存关联
_session.Clear();
Assert.IsFalse(_session.Contains(customer1));
Assert.IsFalse(_session.Contains(customer2));
}
首先,我们加载两个Customer对象,先使用ISession.Evict(object)从缓存中删除一个Customer对象,再使用ISession.Clear()清空缓存,使用Session.Contains(object)检查缓存中的Customer对象。
结语
关于NHibernate一级缓存的内容就这些了,相信你对NHibernate一级缓存有了初步的认识。接下来慢慢探索NHibernate二级缓存吧。
NHibernate教程(19) —— 一级缓存的更多相关文章
- 01-08-01【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate中的一级缓存
缓存的范围? 1.事务范围 事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象形式.缓存的生命周期依赖于事务的生命周期,只有当事务结束时,缓存的生命周期才会结 ...
- NHibernate教程(21)——二级缓存(下)
本节内容 引入 使用NHibernate二级缓存 启用缓存查询 管理NHibernate二级缓存 结语 引入 这篇我还继续上一篇的话题聊聊NHibernate二级缓存剩下的内容,比如你修改.删除数据时 ...
- NHibernate教程(20)——二级缓存(上)
本节内容 引入 介绍NHibernate二级缓存 NHibernate二级缓存提供程序 实现NHibernate二级缓存 结语 引入 上一篇我介绍了NHibernate内置的一级缓存即ISession ...
- [Nhibernate]一级缓存
目录 写在前面 文档与系列文章 一级缓存 一个例子 一级缓存管理 总结 写在前面 上篇文章介绍了nhibernate中对象的三种状态,通过对象的三种状态,很容易想到缓存. 什麽是缓存? 有时候,某些数 ...
- spring管理hibernate,mybatis,一级缓存失效原因
mybatis缓存:一级缓存和二级缓存 hibernate缓存:一级缓存和二级缓存 关于缓存: 缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存中的容器, 其作用是为了减少应 ...
- NHibernate系列文章八:NHibernate对象一级缓存
摘要 Nhibernatea缓存非常强大,按照缓存存储在Session对象还是SessionFactory对象分为一级缓存和二级缓存. 一级缓存存在于Session对象里,也叫Session缓存,由S ...
- NHibernate之一级缓存(第十篇)
NHibernate的一级缓存,名词好像很牛B,很难.实际上就是ISession缓存.存储在ISession的运行周期内.而二级缓存则存储在ISessionFactory内. 一.ISession一级 ...
- 使用NHibernate(9)-- 缓存
1,对象状态. 作为基础,还是先看一下对象的状态吧.主要涉及到三个名词,瞬时.持久.托管. 瞬时态:对象刚创建,Session还不知道这个对象的存在.可以通过调用ISession的Save等方法可以转 ...
- MyBatis一级缓存引起的无穷递归
MyBatis一级缓存引起的无穷递归 引言: 最近在项目中参与了一个领取优惠劵的活动,当多个用户领取同一张优惠劵的时候,使用了数据库锁控制并发,起初的设想是:如果多个人同时领一张劵,第一个到达的人领取 ...
随机推荐
- jquery.cityselect.js基于jQuery+JSON的省市或自定义联动效果
一.插件介绍 最早做省市联动的时候都特别麻烦,后来在helloweba的一篇文章中看到这个插件,很不错的,后来就一直用了. 省市区联动下拉效果在WEB中应用非常广泛,尤其在一些会员信息系统.电商网站最 ...
- Intger To Roman
这题意思是将一个输入的整型阿拉伯数字转化为罗马数字. 思路是将1-10对应的罗马数字放在字符串数组里,然后发现数据变化规律即可,eg:389 = 300 + 89 +9 分别对应的罗马数字. publ ...
- NYOJ--257--郁闷的C小加(一)(中缀表达式变后缀表达式 )
郁闷的C小加(一) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说 ...
- git入门大全
前言 以前写个一个git小结,但是实际上并不够用.于是结合实际工作上碰到的一些情况,参考了一些资料,重新总结了一下.目标是在日常工作中不用再去查阅其他的资料了,如果有什么遗漏或者错误的地方,请评论指出 ...
- sublime text3 配置使用
前言 sublime text3 是一款优秀的代码编辑器,很多好用的功能让我成为其忠实用户. 流程 1.安装完成后首先配置package control,把下面的代码复制到sublime 的控制台: ...
- Entity Framework Core 2.0 新特性
本文翻译来自:https://docs.microsoft.com/en-us/ef/core/what-is-new/index 一.模型级查询过滤器(Model-level query filte ...
- 再起航,我的学习笔记之JavaScript设计模式09(原型模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...
- 利用JS做网页特效——大图轮播
大图轮播完整流程代码操作: <style> * { margin: 0px; padding: 0px; ...
- U3D学习入门
U3D最重要的五大界面 第一:场景(Sence),构建游戏的地方: 第二:层级(Hierarchy),场景中的游戏对象都列在这里. 第三:检测面板(Inspector),当前选中的资源或对象的设置,是 ...
- softmax函数
该函数作用于输出层之上,用于改善输出层神经元饱和时与该神经元直接相关的w和bias学习率下降的问题. 定义: 这表明,在用柔性最大值函数定义输出神经元的输出时,神经元的输出是一种概率分布,所有输出层神 ...