HQL查询会使用Hibernate二级缓存吗

Posted

技术标签:

【中文标题】HQL查询会使用Hibernate二级缓存吗【英文标题】:Will HQL query use Hibernate second-level cache 【发布时间】:2014-08-12 02:11:35 【问题描述】:

我想澄清一些关于hibernate二级缓存的问题。需要澄清的一点是,HQL 查询是否总是会访问数据库(至少对于获取 id)。

假设我们有实体

class Customer 

    long id;  // Primary key

    String name;

    set <Address> addressList;   // One to many relationship



class Address

    long id; // Primary key

    String houseName;


Address 的数据库表具有对 Customer (id) 的外键引用,以支持一对多关系。

作为先决条件,我已将休眠的二级缓存启用为 EHcache。只有实体和关联设置为可缓存。查询缓存未启用。

我知道,如果我多次使用 session.get() 或 session.load(),只有第一次调用会触发对数据库的查询,后续调用将从 2 级缓存中获取数据。

我的问题是

1) HQL 是否会利用二级缓存。 在一个会话中,我执行了一个 HQL 以使用主键 (id) 获取对象,“来自 Customer c where c.id = ?”).setParameter(1, 1005)。

如果我在不同的会话中运行相同的 HQL,客户对象是从 2 级缓存中获取还是会再次访问数据库。

2) 考虑执行另一个 HQL from Customer as c left join fetch c.addressList 以选择客户和关联地址。

如果我在不同的会话中运行相同的 HQL,是否会从二级缓存中获取关联的地址,否则它将再次访问数据库。

【问题讨论】:

是的,HQL 使用二级缓存,但前提是您将 hibernate.query_cache 设置为 true 并在查询中使用 setCacheable(true) 【参考方案1】:

由于您尚未启用Query Cache,因此没有实体查询(JPQL 或 Criteria API)将使用二级缓存。因此,这两个查询都将针对数据库执行。

如果您希望这些查询改为使用二级缓存,您可以启用查询缓存。

【讨论】:

感谢@VlanMihalcea。对于问题 1,我相信休眠将运行查询并获取与搜索条件匹配的所有表行的 id。然后它将使用 id 加载对象。可以根据可用性从级别 2 或数据库加载对象。这并不奇怪,我这里只是通过 ID 搜索,但仍然需要去 DB 再次获取相同的 ID。 按 id 搜索是一种覆盖默认获取机制的方法,因此您可以显式声明新的获取计划,并且查询可以在执行之前触发刷新,这就是它不执行的原因t 简单地忽略所有那些从一级或二级缓存返回实体。 请找类似的帖子link

以上是关于HQL查询会使用Hibernate二级缓存吗的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate查询连接池二级缓存

hibernate 一级缓存,二级缓存,查询缓存

Hibernate中一级缓存和二级缓存使用详解

Hibernate一级缓存和二级缓存具体解释

11hibernate查询连接池二级缓存

hibernate里,get方法会访问二级缓存吗