根据我的理解,当使用主键加载对象时,将使用二级缓存。这包括获取关联。我只能想到session.get(),session.load方法,其中二级缓存将进入图片。
如果关联是集合或其他实体,它是如何缓存的?例如: -
@Cacheable
public class Department{
private List Employees;
private DepatmentDetail detail ;
}
如何使关联员工和详细信息可缓存?我想我需要在协会员工和细节之上提及@cache。 但那不起作用?
当开发人员执行department.getEmployees()时,hibernate会在内部触发查询,即
select * from employees where deptId =1;
现在,如果我使用查询缓存,我明确地进行上述查询并获取结果,将再次向db发出查询。为什么再次触发查询。我认为这与hibernate内部存储二级缓存和查询缓存的结果有关(它们可能存储在不同的区域中)。如果有人可以对这方面有所了解,那就太棒了。
答案 0 :(得分:7)
请查看下面详细解释的链接。
查询级缓存:
Hibernate还为查询结果集实现了一个缓存,它与二级缓存紧密集成。
这是一个可选功能,需要两个额外的物理缓存区域来保存缓存的查询结果和上次更新表时的时间戳。这仅适用于使用相同参数频繁运行的查询。
二级缓存
Hibernate与多个二级缓存提供程序兼容。任何实现都可以用于二级缓存。
差异:
查询缓存的唯一目的是缓存查询,而第二缓存也可用于缓存其他缓存。
查询缓存由Hibernate内部提供,而对于二级缓存,您必须选择一些外部二级缓存,如Infinispan,EHCache等。
答案 1 :(得分:3)
二级缓存在内部具有类似哈希表的结构来保存数据。这里的密钥将是实体的标识符,值将是实体的脱水值。要从这个L2缓存中获取数据,您必须拥有密钥,即实体的标识符。 很明显,您可以将它用于通过id获取实体的方法。
当您使用L2缓存启用query_cache时,此方案也会更改。查询缓存存储查询及其对应的结果集实体ID。 现在,即使您没有通过id获取(使用JPQL或HQL OR queryDsl),hibernate也会检查是否先前触发了相同的查询,如果是,则从查询缓存中获取ID列表。之后返回L2缓存中对应于相同ID的实体。
答案 2 :(得分:0)
我们需要在集合上明确放置@Cache(usage=CacheConcurrencyStrategy.<VALUE>)
,在相应的集合类上明确放置@Cacheable
。
hibernate二级缓存here有一个非常好的解释。