理解 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一级缓存的更多相关文章

  1. Hibernate一级缓存(基于查询分析)

    首先我们应该弄清什么是hibernate缓存:hibernate缓存是指为了降低应用程序对物理数据源的访问频次,从而提高应用程序的运行性能的一种策略.我们要将这个跟计算机内存或者cpu的缓存区分开. ...

  2. hibernate一级缓存及对象的状态

    hibernate中实体类对象的状态 在hibernate中实体类对象有三种状态 (1)瞬时态(临时态) 瞬时态:即我们自己创建一个对象,还没有保存到数据库就叫临时态,其实也可以说是对像没有id值,跟 ...

  3. Hibernate一级缓存(补)

    ------------------siwuxie095                                 什么是缓存         缓存是介于应用程序和永久性数据存储源(如:硬盘上的 ...

  4. Hibernate一级缓存测试分析

    Hibernate 一级缓存测试分析 Hibernate的一级缓存就是指Session缓存,此Session非http的session会话技术,可以理解为JDBC的Connection,连接会话,Se ...

  5. 转载 hibernate一级缓存和二级缓存的区别

    文章来源:http://blog.csdn.net/defonds/article/details/2308972     hibernate一级缓存和二级缓存的区别 缓存是介于应用程序和物理数据源之 ...

  6. Hibernate一级缓存和三种状态

    Hibernate一级缓存又称session缓存,生命周期很短,跟session生命周期相同. 三种状态:1.transient(瞬时态):刚new出来的对象,既不在数据库中,也不在session管理 ...

  7. hibernate一级缓存的源码初窥

    hibernate的一级缓存的存在使得hibernate可以在操作实体化对象的时候减少对于数据库的访问.hibernate的一级缓存实际上就是指的session缓存,它的生命周期和session相同. ...

  8. Hibernate 一级缓存的陷阱

    最近公司的应用经常报OOM,一开始我以为是公司业务数据太多,导致内存不够,所以只是简单的把容器的内存加大.撑了几天后这个错仍然被报出来.后来我仔 细分析过项目代码后,没有发现有任何引起内存泄漏的地方. ...

  9. Hibernate <一级缓存>

    Hibernate缓存分为三级: 一级缓存:基于事务级别(内存)的缓存,也可以成为session级别缓存 二级缓存:依赖于第三方,当请求一个对象时,先在缓存里面查找,如果没有就执行查询语句 查询缓存: ...

随机推荐

  1. C++学习进度0

    昨天,又把<C++ primer> 刷了一遍,这一次看的是陈硕大大的评注版,重点看了陈硕的注释,<Accelerated C++>去年就把代码巧了一遍,<C++ prim ...

  2. AngularJS的学习笔记(一)

    声明:单纯作为我自己的学习笔记,纯是为了自己学习,上面的话都是从各处粘贴,如有冒犯,请原谅我这个小菜鸟~ AngularJS使用了不同的方法,它尝试去补足HTML本身在构建应用方面的缺陷. 使用双大括 ...

  3. 重写equals方法

    用下面的例子来进行解释. String name; int id; @Override public boolean equals(Object otherObject) { if (this == ...

  4. python2.7安装matplotlib遇到的问题及解决方法

    python2.7下import matplotlib报错 第一个报错是:缺少这个pyparsing-2.1.4.win32-py2.7.exe 直接下载安装就行 第二个报错是:缺少cycler 这个 ...

  5. UIButtonTypeSystem backBarButtonItem

    当UIButton是UIButtonTypeSystem类型时,改变UIButton的frame,系统会有一个动画改变效果,不想要这个效果,将类型改为UIButtonTypeCustom. backB ...

  6. 区分PC端与移动端代码,涵盖C#、JS、JQuery、webconfig

    1)C#区分PC端或移动端 using System.Text.RegularExpressions string u = Request.ServerVariables["HTTP_USE ...

  7. win7下Outlook2010禁止访问具有潜在不安全因素的附件的解决办法

    发生情景: 收到.bat .exe等敏感类型附件时,会碰到此问题. 解决方法: 1.打开regedit.exe 2.依次展开HKEY_CURRENT_USER\Software\Microsoft\O ...

  8. jquery.get()

    1.获取当前jquery对象匹配到的dom元素 2.语法: jqueryObject.get([index]) //jQueryObject[index]等价于jQueryObject.get(ind ...

  9. win7配上的网关会自动消失?解决

    前几天遇见一台计算机,发现手动设置的ip和网关等...在使用了一会就变成,网关丢失,其他不变...奇怪啊...第一次遇见.后来找了一下.有答案了. 先将客户端卸载掉,再打开网络和共享中心-->本 ...

  10. Win7 下IIS(7.5)发布 ASP.NET MVC

    操作系统 Win 7 旗舰版 开发工具 VS2015 使用技术 IIS7.5 + MVC4.0 一 . 在IIS上部署程序后出现错误-当前标识(NT AUTHORITY/NETWORK SERVICE ...