hibernate:真正理解二级缓存和查询缓存

翻译 2015年11月21日 15:07:50

关于hibernate的O/R映射我已经写了多篇文章,并且受到了广泛的欢迎。hibernate不仅仅是社区上一个受欢迎的小孩,他实际上是非常强大一致和可信赖的数据库映射工具。映射Java中的对象到关系型数据库中有很多你需要知道的面。hibernate为了线程简单的启动做了特殊的处理,并为了超复杂的映射提供了便利。

数据库和你的Java对象间的映射一个主要的关注点是性能问题,那些没有花太多时间使用hibernate的人关心的问题是,这个O/R映射工具将会限制在性能上的提高。今天我将在二级缓存和查询缓存这两个方面来讨论他们关心的性能问题。

二级缓存

二级缓存被称作是二级的是因为在hibernate中在session打开的时候已经有一个缓存,从hibernate文档中我们可以看到:一个hibernate session是对于持久数据的事务级别的缓存,配置一个簇或者JVM级别(sessionfactory级别)的缓存是有可能的,缓存永远都不知道通过其他程序对持久化数据做的改变(可以配置过期时间)。正如上边提到的,二级缓存存在的时间和session factory存在时间一样长。二级缓存保存标记缓存的实体的属性和关联。
这里我不在详细介绍hibernate开发文档中的内容,所以对一些细节性的东西请参考它的开发文档。我只想说最重要的部分是添加在你的映射文件中的cache。
<cache usage="transactional|read-write|nonstrict-read-write|read-only" />

对于大多数读者,我到此为止描述的东西并没有什么新鲜的,相信我,马上就会讲到正题。

查询缓存

另一个有用的缓存是查询缓存,查询缓存有效的为特定的查询保存特定的实体,下边是文档中的描述:注意查询缓存并不在结果集中缓存实体的状态,它只缓存实体的值和实体的值得类型,所以查询缓存总是和二级缓存一起使用。关于它的配置可以在官方文档中查看。一旦在你的hibernate中配置生效,他就会简单的调用setCacheable(true)在你的查询或者事务对象上。

二级缓存是如何工作的

理解缓存的关键之一是理解他们在内部是怎么工作的,二级缓存尤其需要这样理解,特别是当处理大而复杂的对象而且需要频繁查询和加载的时候。第一件需要理解的事是二级缓存不缓存需要缓存的对象类型的实例,相反的它缓存的是对象属性的独立的值,对像下边这个对象:
public class Person {
 private Person parent;
 private Set<Person> children;
 
 public void setParent(Person p) { parent = p; }
 public void setChildren(Set<Person> set) { children = set; }
 
 public Set<Person> getChildren() { return children; }
 public Person getParent() { return parent; }
}
...with a mapping like this:

<class name="org.javalobby.tnt.hibernate.Person">
 
<cache usage="read-write"/>

  <id name="id" column="id" type="long">
   <generator class="identity"/>
  </id>
  <property name="firstName" type="string"/>
  <property name="middleInitial" type="string"/>
  <property name="lastName" type="string"/>
  <many-to-one name="parent" column="parent_id" class="Person"/>
  <set name="children">
   <key column="parent_id"/>
   <one-to-many class="Person"/>
  </set>
</class>

hibernate会为这个类按照以下的方式加载这个类的记录
*-----------------------------------------*
|          Person Data Cache              |
|-----------------------------------------|
| 1 -> [ "John" , "Q" , "Public" , null ] |
| 2 -> [ "Joey" , "D" , "Public" ,  1   ] |
| 3 -> [ "Sara" , "N" , "Public" ,  1   ] |
*-----------------------------------------*

所以在这个例子中,hibernate保存了3个字符串和为many-to-one关系的一个序列化的id,我重申一下hibernate不保存实际对象的实例。为什么这个非常重要呢,有两点,一:hibernate不需要担心客户端操作缓存中对象的代码;二:关系和关联不会变的‘陈旧’,很容易保持最新的数据。缓存不是树形的对象,是概念上的map数组,我使用‘概念上的’因为hibernate在缓存后提供了很多支持。

原文地址:http://www.javalobby.org/java/forums/t48846.html

hibernate一级缓存和二级缓存的区别

       缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在...
  • defonds
  • defonds
  • 2008年04月20日 13:40
  • 95366

hibernate中一级缓存和二级缓存的具体区别

Hibernate缓存分类: 一、Session缓存(又称作事务缓存):Hibernate内置的,不能卸除。 缓存范围:缓存只能被当前Session对象访问。缓存的生命周期依赖于S...
  • u013047660
  • u013047660
  • 2014年05月01日 23:50
  • 1332

hibernate 缓存

简介缓存 缓存是广泛使用的用于优化数据库应用程序。缓存的目的是减少你的应用程序,并通过保存从数据库已加载数据的数据库之间的流量。检索数据当前未在高速缓存仅当数据库访问是必要的。应用程序可能需要从时间空...
  • u012743772
  • u012743772
  • 2016年04月11日 11:13
  • 3191

【hibernate框架】缓存机制之查询缓存

查询缓存是面对重复缓存的,是依赖于二级缓存的,所以一定要打开二级缓存。 1.load默认使用二级缓存,iterate默认使用二级缓存 2.list默认往二级缓存中加数据,但是查询的时候不使用 3.如...
  • u013517797
  • u013517797
  • 2015年03月08日 12:56
  • 838

Hibernate开启了二级缓存后查询语句为什么没有被缓存

原文地址:https://developer.jboss.org/wiki/HibernateFAQ-CommonProblems I've enabled the second-level...
  • tanga842428
  • tanga842428
  • 2016年09月25日 16:11
  • 395

hibernate缓存机制详细分析(一级、二级、查询缓存,非常清晰明白)

在本篇随笔里将会分析一下hibernate的缓存机制,包括一级缓存(session级别)、二级缓存(sessionFactory级别)以及查询缓存,当然还要讨论下我们的N+1的问题。 随笔虽长,但我...
  • w1033162186
  • w1033162186
  • 2016年02月05日 16:33
  • 776

Hibernate获取数据方式与缓存使用

Hibernate获取数据的方式有不同的几种,其与缓存结合使用的效果也不尽相同,而Hibernate中具体怎么使用缓存其实是我们很关心的一个问题,直接涉及到性能方面。 缓存在Hibernate中主要...
  • timliang18601860
  • timliang18601860
  • 2011年08月30日 19:19
  • 388

hibernate,hql与sql的缓存使用

1.在hibernate中createQuery执行hql查询的时候使用查询缓存:   getSession().createQuery(hql).setCacheable(true).setCa...
  • diquren
  • diquren
  • 2014年04月14日 17:57
  • 1882

MyBatis缓存分为一级缓存和二级缓存(二)

MyBatis 缓存 MyBatis缓存分为一级缓存和二级缓存 一级缓存 MyBatis的一级缓存指的是在一个Session域内,session为关闭的时候执行的查询会根据SQL为key被缓...
  • u014756827
  • u014756827
  • 2016年10月08日 10:54
  • 1557

Hibernate的一级和二级缓存

1. 管理session session对象的生命周期与本地线程绑定 thread 使用本地线程绑定,每次都从当前的线程提取session!!!     * 当前线程如果存在session对象,取...
  • zdp072
  • zdp072
  • 2016年04月13日 21:38
  • 3209
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hibernate:真正理解二级缓存和查询缓存
举报原因:
原因补充:

(最多只允许输入30个字)