Hibernate一级缓存测试分析
Hibernate 一级缓存测试分析
Hibernate的一级缓存就是指Session缓存,此Session非http的session会话技术,可以理解为JDBC的Connection,连接会话,Session缓存就是一块内存空间,用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先使用对象的OID(Object ID)在Hibernate 的一级缓存空间进行查找,如果通过OID匹配到了对象,就直接从一级缓存中取出使用,如果没有找到匹配该OID值的对象,这才会进行查询数据库。当从数据库中查询数据的时候,该数据就会被放入到Session缓存中,目的就是为了减少数据库的访问次数,从而提高性能。
Hibernate缓存特点
- 当应用程序调用Session接口的 save(), update(), saveOrUpdate() 时候,如果缓存中没 有相应的对象,Hb就会自动的把查询信息加入到缓存。
- 当应用程序调用Session接口的 load(), get(), list() 等查询方法的时候,会进行判断缓存中是否有数据,同摘要。
- 当应用程序调用Session接口的 close() Session缓存会被清空
接下来进行测试一级缓存
首先测试一级缓存是否存在?对user表的主键为“1”的分别进行两次查询:
public void demo1 (){
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
User user1 = session.get(User.class, "1");
System.out.println(user1);
System.out.println("-------------");
User user2 = session.get(User.class, "1");
System.out.println(user2);
System.out.println(user1 == user2);
transaction.commit();
session.close();
}
运行结果:

我们发现第一次执行Session的get()方法的时候,由于一级缓存中没有数据,所以会向数据库发送一条sql语句进行查询,第二次调用get()的时候,则不会发送sql语句,而是从一级缓存中取的,所以user和user2的内存地址相等
一级缓存的快照区
Hibernate向一级缓存放入数据的时候,同时复制一份放到Hibernate快照中,当使用commot()提交事务的时候,同时会清理Session的一级缓存,这是会用OID判断一级缓存中的对象和快照中的对象是否一致,如果一致则执行 update 语句,将缓存中的内容同步到数据库,并且更新快照,这也就实现了不使用 update 语句就可以自动更新数据库,Hibernate快照的作用也就是为了保持缓存中的数据和数据库中的数据的一致性。
快照区代码测试
我们在get的时候设置断点,看到右侧变量 session->persitenceContext->entitlxxx->head,也就是缓存中是为空的
现在继续执行
我们发现在缓存区域已经有了数据了,同时Hibernate 也会在快照区域创建数据,在 Hibernate3 里面它使用的是Map进行存储的,map的key作为一级缓存去,value作为一级快照区,当进行查询的时候,会同时给缓存和快照去放入相同的数据,当orm对象属性发生变化的时候,会首先改变缓存区的值,当进行事务提交的时候,会比较缓存和快照的内容,如果一致则不操作,不一致则更新数据库。
继续执行:
commin()的时候,自动进行更新,clear().evict()的时候会清除缓存(删除表中数据的时候也会)
public void demo1 (){
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
User user1 = session.get(User.class, "1");
System.out.println(user1);
System.out.println("-------------");
session.clear();
User user2 = session.get(User.class, "1");
System.out.println(user2);
System.out.println(user1 == user2);
transaction.commit();
session.close();
}
输入如下:
Hibernate:
select
user0_.uid as uid1_1_0_,
user0_.name as name2_1_0_,
user0_.username as username3_1_0_,
user0_.password as password4_1_0_,
user0_.email as email5_1_0_,
user0_.telephone as telephon6_1_0_,
user0_.sex as sex7_1_0_
from
user user0_
where
user0_.uid=?
User{uid=1, username=baiChaoHua, password=null, name=null, email=null, telephone=null, birthady=null, sex=null, state=0, code=null}
-------------
Hibernate:
select
user0_.uid as uid1_1_0_,
user0_.name as name2_1_0_,
user0_.username as username3_1_0_,
user0_.password as password4_1_0_,
user0_.email as email5_1_0_,
user0_.telephone as telephon6_1_0_,
user0_.sex as sex7_1_0_
from
user user0_
where
user0_.uid=?
User{uid=1, username=baiChaoHua, password=null, name=null, email=null, telephone=null, birthady=null, sex=null, state=0, code=null}
false
可以看出执行执行了两次sql,user对象的内存地址也就自然不一样
一级缓存常用的API:
clear():清空一级缓存。evict():清空一级缓存中指定的某个对象。refresh():重新查询数据库,用数据库中的信息来更新一级缓存与快照区。
未完待续...
Hibernate一级缓存测试分析的更多相关文章
- Hibernate一级缓存(基于查询分析)
首先我们应该弄清什么是hibernate缓存:hibernate缓存是指为了降低应用程序对物理数据源的访问频次,从而提高应用程序的运行性能的一种策略.我们要将这个跟计算机内存或者cpu的缓存区分开. ...
- hibernate一级缓存
理解 Hibernate 一级缓存 Hibernate 一级缓存默认是打开,不需要任何的配置.实际上,你无法强制禁止它的使用. 如果你理解了一级缓存实际上和会话是关联的,就很容易理解一级缓存.总所周知 ...
- hibernate一级缓存及对象的状态
hibernate中实体类对象的状态 在hibernate中实体类对象有三种状态 (1)瞬时态(临时态) 瞬时态:即我们自己创建一个对象,还没有保存到数据库就叫临时态,其实也可以说是对像没有id值,跟 ...
- Hibernate一级缓存(补)
------------------siwuxie095 什么是缓存 缓存是介于应用程序和永久性数据存储源(如:硬盘上的 ...
- 转载 hibernate一级缓存和二级缓存的区别
文章来源:http://blog.csdn.net/defonds/article/details/2308972 hibernate一级缓存和二级缓存的区别 缓存是介于应用程序和物理数据源之 ...
- Hibernate一级缓存和三种状态
Hibernate一级缓存又称session缓存,生命周期很短,跟session生命周期相同. 三种状态:1.transient(瞬时态):刚new出来的对象,既不在数据库中,也不在session管理 ...
- hibernate一级缓存的源码初窥
hibernate的一级缓存的存在使得hibernate可以在操作实体化对象的时候减少对于数据库的访问.hibernate的一级缓存实际上就是指的session缓存,它的生命周期和session相同. ...
- Hibernate 一级缓存的陷阱
最近公司的应用经常报OOM,一开始我以为是公司业务数据太多,导致内存不够,所以只是简单的把容器的内存加大.撑了几天后这个错仍然被报出来.后来我仔 细分析过项目代码后,没有发现有任何引起内存泄漏的地方. ...
- Hibernate <一级缓存>
Hibernate缓存分为三级: 一级缓存:基于事务级别(内存)的缓存,也可以成为session级别缓存 二级缓存:依赖于第三方,当请求一个对象时,先在缓存里面查找,如果没有就执行查询语句 查询缓存: ...
随机推荐
- P3157 [CQOI2011]动态逆序对
P3157 [CQOI2011]动态逆序对 https://www.luogu.org/problemnew/show/P3157 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai&g ...
- jQuery对象转换为DOM对象(转)
jQuery对象转换为dom对象 只有jQuery对象才能调用jQuery类库的各种函数,同样有些dom对象的属性和方法在jQuery上也是无法调用的,不过基本上jQuery类库提供的函数包含了所有的 ...
- ASP.NET中修改从数据库获取的datatable中的值
有些时候,我们从数据库表中获取一个实体的对象,但有些内容并不是最终显示的内容,格式也都是不一样.经过一番尝试,发现datatable中的数值如果跟想要改变的类型不一致,就无法更改,只有添加新列,然后把 ...
- python数据类型内部结构解剖
一.前言 我们知道,python是一种动态语言,可以将任何类型的数据赋给任何变量,譬如: # Python代码 x = 4 x = "four" 这里已经将 x 变量的内容由整型转 ...
- iOS 管理库 Carthage 安装以及使用
https://blog.csdn.net/Mazy_ma/article/details/70185547
- iOS - xcode - label 字体自动根据宽高 显示完全
1. label 左右约束要给. 2.代码实现label.adjustsFontSizeToFitWidth = YES
- [leetcode]238. Product of Array Except Self除了自身以外的数组元素乘积
Given an array nums of n integers where n > 1, return an array output such that output[i] is equ ...
- 有关于mfc webbrowser插件的使用
最近写的东西中常常需要嵌入一些浏览器,微软提供了一个比较好的接口,可以在MFC写的程序中嵌入一个简易的浏览器,是以ActiveX插件的形式提供的接口,使用起来也比较的方便,这里我就简单记录下这个插件的 ...
- python的代码检查
#!/bin/python3.4# coding=utf-8 class lexicon(object): # direction = ['north', 'south', 'east', 'west ...
- Codeforces 703B. Mishka and trip 模拟
B. Mishka and trip time limit per test:1 second memory limit per test:256 megabytes input:standard i ...


