gpt4 book ai didi

Hibernate 一级缓存与查询缓存

转载 作者:行者123 更新时间:2023-12-02 23:42:35 28 4
gpt4 key购买 nike

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

最佳答案

是的,是不同的东西。就像 Lee Chee Kiam 所说,一级缓存默认启用,您无法禁用它。基本上这是 Hibernate 第一次放置获取的实体的地方,因此同一对象的第二次查询不会实例化新对象,甚至可以避免通过 ID 进行查询。关于此的一个例子here .

//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 实现模式。

查询缓存与实体严格相关,它在搜索条件和满足特定查询过滤器的实体之间建立关联(来自 here )。查询缓存仅将查询的原始结果作为主键(在 hibernate 中称为 id)保存。 它不容纳实际的水合物体

查询缓存如何工作?

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

session.createCriteria(Person.class)
.add( Restrictions.eq("firstName", "Joey")
).setCacheable(true);

查询缓存在概念上看起来像一个 HashMap ,其中键由查询文本和参数值组成,值是与查询匹配的实体 ID 列表

*----------------------------------------------------------*
| Query Cache |
|----------------------------------------------------------|
| ["from Person where firstName=?", ["Joey"] ] -> [1, 2] ] |
*----------------------------------------------------------*

因此,下次我们执行相同的条件查询时,Hibernate 将查看该 HashMap 并解析 id 为 1 和 2 的人员是否符合限制。在这种情况下,您将避免查询的成本(在这种情况下几乎为零,但可能是带有连接等的昂贵查询),但您仍然会访问数据库来查询人员(现在通过 id 什么是非常快)用于构造 Person 对象。查询缓存经常与二级缓存一起使用,这需要第三方实现,例如 Ehcache 或 infinispan。

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

*-----------------------------------------*
| 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 的 Person 对应的对象。

查询缓存和二级缓存适用于读取次数较多、更新次数很少或为零的实体。因为众所周知的问题是每种类型的缓存不一致。因此,Hibernate 需要使缓存无效或刷新(如果您有集群缓存,则包括复制)。随着许多更新的进行,您将不断地使缓存失效,这弊大于利。

一些解释取自此great post你应该阅读这个good answer也是。

关于Hibernate 一级缓存与查询缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19516451/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com