hibernate一级缓存
理解 Hibernate 一级缓存
Hibernate 一级缓存默认是打开,不需要任何的配置。实际上,你无法强制禁止它的使用。
如果你理解了一级缓存实际上和会话是关联的,就很容易理解一级缓存。总所周知,会话是当我们需要时从会话工厂创建并且一旦会话关闭,缓存就会丢失。相似的,一级缓存与会话对象相关联,在会话存活期间是可用的。相同应用中的不同会话是无法相互访问的。
重点##
- 一级缓存和会话相关联,应用中的会话无法知道其他会话中的缓存
- 缓存的范围是在会话范围内。一旦会话被关闭,缓存将永远消失
- 一级缓存默认是打开的,并无法禁止
- 第一次查询一个实体会从数据库中检索,并被存放在与 hibernate 会话关联的一级缓存中
- 如果在一个会话中再次查询该实体,它将从一级缓存中加载,不会发送 sql 查询到数据库
- 加载的实体可以从会话中被移除,通过使用
evict()方法。如果实体已经使用evict下次加载该实体将会再次调用数据库查询 - 整个会话缓存可以通过
clear()方法移除。它将移除缓存中的所有实体
从一级缓存检索的例子
在下面的例子中,将通过 hibernate 会话从数据库检索 Department 实体。多次检索该实体,观察 sql 语句是否被发出去。
//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
//fetch the department entity from database first time
DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
//fetch the department entity again
department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
session.getTransaction().commit();
HibernateUtil.shutdown();
Output:
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource
从输出来看,第二次 session.load() 语句并没有执行 select 查询,而是直接加载 department 实体。说明实体对象却是被缓存了。
新会话测试一级缓存
如果实体已经在一个会话中被获取,在新会话中,该实体将再次从数据库中获取。
//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Session sessionTemp = HibernateUtil.getSessionFactory().openSession();
sessionTemp.beginTransaction();
try
{
//fetch the department entity from database first time
DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
//fetch the department entity again
department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
department = (DepartmentEntity) sessionTemp.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
}
finally
{
session.getTransaction().commit();
HibernateUtil.shutdown();
sessionTemp.getTransaction().commit();
HibernateUtil.shutdown();
}
Output:
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
从输出可以发现及时 department 实体已经被存储在会话中,但是 sessionTemp 会话还是发出了一条数据库查询语句。说明不同会话之间的缓存是相互不可见的。
将实体对象从一级缓存中移除
虽然无法禁用 hibernate 一级缓存,但是如果需要的话,可以移除该缓存对象。通过使用一下两个方法:
evict()clear()
evict() 用于移除会话中的指定缓存对象,clear() 方法则用于移除会话中的所有缓存对象。一下代码展示移除一个缓存对象和移除所有缓存对象。
//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
try
{
//fetch the department entity from database first time
DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
//fetch the department entity again
department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
session.evict(department);
//session.clear();
department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
}
finally
{
session.getTransaction().commit();
HibernateUtil.shutdown();
}
Output:
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
从输出结果很明显可以看出,evict() 方法将 department 实体从一级缓存中移除,所以他再次从数据库中获取。
本文内容来自:http://howtodoinjava.com/hibernate/understanding-hibernate-first-level-cache-with-example/。本文只是翻译以及润色
欢迎转载,但请注明本文链接,谢谢你。
2016.9.21 9:08
hibernate一级缓存的更多相关文章
- Hibernate一级缓存(基于查询分析)
首先我们应该弄清什么是hibernate缓存:hibernate缓存是指为了降低应用程序对物理数据源的访问频次,从而提高应用程序的运行性能的一种策略.我们要将这个跟计算机内存或者cpu的缓存区分开. ...
- hibernate一级缓存及对象的状态
hibernate中实体类对象的状态 在hibernate中实体类对象有三种状态 (1)瞬时态(临时态) 瞬时态:即我们自己创建一个对象,还没有保存到数据库就叫临时态,其实也可以说是对像没有id值,跟 ...
- Hibernate一级缓存(补)
------------------siwuxie095 什么是缓存 缓存是介于应用程序和永久性数据存储源(如:硬盘上的 ...
- Hibernate一级缓存测试分析
Hibernate 一级缓存测试分析 Hibernate的一级缓存就是指Session缓存,此Session非http的session会话技术,可以理解为JDBC的Connection,连接会话,Se ...
- 转载 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级别缓存 二级缓存:依赖于第三方,当请求一个对象时,先在缓存里面查找,如果没有就执行查询语句 查询缓存: ...
随机推荐
- ROS语音交互(四)接入图灵语义理解
首先程序中会用到Json,curl 安装相应的库 $ sudo apt-get install libcurl3 libcurl4-openssl-dev$ sudo apt-get install ...
- 通过InputStream访问文件中的数据的四种方法
//方法一(每次只读取一个字节) public static void getFile() throws IOException { File file = new File("D:\\a. ...
- Delphi: 有关Form处理 :需要调用的时候进行调用。
if not Assigned(frmAppServer) then frmAppServer := TfrmAppServer.Create(Application); frmAppServer.S ...
- js页面跳转的方式
js方式的页面跳转1.window.location.href方式 <script language="javascript" type="text/java ...
- c4,configure the debug environment
Yesterday I found a tiny C compiler (less than 600 line of C code, containing commits) called " ...
- 第一章 JavaScript简史
JavaScript: 一种使网页具有交互能力的程序设计语言. BOM: 浏览器对象模型,指通过JS用来调整Web浏览器的高度.宽度和位置属性的办法. DHTML: 1.利用HTML标记各种元素 ...
- swift 闭包循环引用
当使用闭包时,类本身持有self,然后又在闭包中访问了self或者self的属性,就会导致恶心额循环引用.swift提供的解决方法是在闭包中定义捕获列表,捕获列表是闭包想怎么引用捕获来的变量.例如下面 ...
- ACM 字符串 题目整理
AC自动机 UVa 11468 Substring AC自动机+概率DP. 注意要补全不存在的边. 为什么要补全不存在的边呢?补全以后可以直接找到状态的转移,即从所有子节点就可以实现所有状态转移. ...
- 解决maven生成的web项目下的servlet.jar与tomcat自带servlet.jar冲突的问题
使用maven生成web工程后,编译需要下servlet-api.jar和jsp-api.jar文件. pom文件中的写法为: <dependency> <groupId>ja ...
- android SDK 离线下载更新
http://blog.csdn.net/harvic880925/article/details/37913801 前言:在公司配置eclipse做android开发,真是烦死了,不知公司做了哪门子 ...