首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Hibernate一级缓存与查询缓存

Hibernate一级缓存与查询缓存
EN

Stack Overflow用户
提问于 2013-10-22 11:21:27
回答 2查看 3.6K关注 0票数 5

第一级缓存与hibernate中的查询缓存不同吗?我看过关于第一级和查询缓存的文章,所以我很困惑。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-07 12:03:35

第一级缓存在默认情况下是启用的,并且是每个会话的基础。查询缓存默认不启用,在多个会话之间共享,应该始终与第二级缓存一起使用。

要启用查询缓存,应使用以下属性:

代码语言:javascript
复制
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=org.hibernate.cache.EhCacheProvider
hibernate.cache.use_query_cache=true
票数 6
EN

Stack Overflow用户

发布于 2015-08-03 16:54:38

是的,是不同的东西。正如Lee Chee Kiam所说,默认情况下,第一级缓存是启用的,您不能禁用它。基本上,Hibernate第一次将获取的实体放在那里,这样同一个对象的第二个查询就不会实例化一个新对象,甚至避免查询(如果是ID )。

代码语言:javascript
复制
//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

我们可以说,第一级缓存是IdentityMap模式的Hibernate实现。

查询缓存与实体严格相关,它将搜索条件与执行特定查询筛选器的实体(来自这里)进行关联。查询缓存只将查询的原始结果作为主键保存,在hibernate the中,id的.中,它不包含实际的水合对象

查询缓存是如何工作的?

假设我们有以下条件查询:

代码语言:javascript
复制
session.createCriteria(Person.class)
    .add( Restrictions.eq("firstName", "Joey")
    ).setCacheable(true);

查询缓存在概念上类似于哈希映射,其中键由查询文本和参数值组成,值是与查询匹配的实体Id列表。

代码语言:javascript
复制
*----------------------------------------------------------*
|                       Query Cache                        |                     
|----------------------------------------------------------|
| ["from Person where firstName=?", ["Joey"] ] -> [1, 2] ] |
*----------------------------------------------------------*

因此,下次执行相同的条件查询时,Hibernate将查看该哈希映射,并解决具有id 1和2的人员与限制匹配的问题。在这种情况下,您将避免查询的成本(在本例中,查询成本几乎为零,但可能是一个带有联接的昂贵查询,等等),但您仍然需要访问用于查询Person对象的数据库(现在使用id,非常快)来构造Person对象。查询缓存经常与第二级缓存一起使用,这需要第三部分实现,如Ehcache或无穷大。

第二级缓存存储实体数据,但不存储实体本身。数据以“脱水”格式存储,该格式看起来像散列图,其中键是实体Id,值是原始值的列表。下面是关于第二级缓存内容的示例:

代码语言:javascript
复制
*-----------------------------------------*
|          Person Data Cache              |
|-----------------------------------------|
| 1 -> [ "Joey" , "Q" , "Public" , null ] |
| 2 -> [ "Joey" , "D" , "Public" ,  1   ] |
| 3 -> [ "Sara" , "N" , "Public" ,  1   ] |
*-----------------------------------------*

因此,查询缓存将给出id 1和2,然后Hibernate将使用第二级缓存中对应于id 1和2的原始数据构造对象。

查询缓存和二级缓存用于具有多个读取和很少或零更新的实体。因为众所周知的每一种缓存类型的不一致性问题。因此Hibernate将需要使缓存失效或刷新(如果有集群缓存,则包含复制)。有了许多更新,您将不断地使缓存无效,而且它将弊大于利。

一些解释是从这个伟大的职位中得到的,你也应该阅读这个很好的答案

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19516451

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档