Java 二级缓存 vs 查询缓存 vs 集合缓存?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23454133/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 23:04:53  来源:igfitidea点击:

Second level cache vs query cache vs collection cache?

javahibernatesecond-level-cache

提问by M Sach

As per my understanding, Second level cache will be used when the objects are loaded using their primary key. This includes fetching of associations.I can think of only above session.get(), session.load methods where second level cache will come in to picture.

根据我的理解,当使用主键加载对象时,将使用二级缓存。这包括获取关联。我只能想到上面的 session.get(), session.load 方法,其中二级缓存将出现。

If association is collection or some other entity , how it can be cached ? For example :-

如果关联是集合或其他实体,如何缓存它?例如 :-

  @Cacheable
  public class Department{
   private List Employees;
   private DepatmentDetail detail ;

}

How can i make association Employees and detail cacheable ? I think i need to mention @cache above associations Employees and detail. But that didn't work?

如何使关联员工和详细信息可缓存?我想我需要在关联员工和细节上面提到@cache。但那没有用?

when developer does department.getEmployees(), hibernate will internally fire the query i.e

当开发人员执行 Department.getEmployees() 时,hibernate 将在内部触发查询,即

 select * from employees where deptId =1;

Now if i use query cache where i explicitly make above query and fetch the results, query will be fired again to db. why query is fired again . I think this is related to how hibernate internally stores the result of second level cache and query cache(they may be stored in separate regions). If somebody can throw light on this aspect also, it will be great.

现在,如果我使用查询缓存,我明确地进行上述查询并获取结果,查询将再次被触发到 db。为什么再次触发查询。我认为这与hibernate内部如何存储二级缓存和查询缓存的结果有关(它们可能存储在不同的区域)。如果有人也能对这方面有所了解,那就太好了。

采纳答案by Braj

Have a look at below links where it is explained in details.

看看下面的链接,那里有详细解释。

Query-level cache:

查询级缓存:

Hibernate also implements a cache for query resultsets that integrates closely with the second-level cache.

This is an optional feature and requires two additional physical cache regions that hold the cached query results and the timestamps when a table was last updated. This is only useful for queries that are run frequently with the same parameters.

Hibernate 还为查询结果集实现了一个缓存,该缓存与二级缓存紧密集成。

这是一个可选功能,需要两个额外的物理缓存区域来保存缓存的查询结果和上次更新表时的时间戳。这仅对使用相同参数频繁运行的查询有用。

Second-level cache

二级缓存

Hibernate is compatible with several second-level cache providers. Any implementation can be used for second level cache.

Hibernate 与多个二级缓存提供程序兼容。任何实现都可以用于二级缓存。

Difference:

区别:

Query Cache's sole purpose is to cache the queries whereas Second Cache can be used to cache for other caches also.

查询缓存的唯一目的是缓存查询,而第二缓存也可用于缓存其他缓存。

Query cache is provided by Hibernate internally whereas for Second level cache you have to choose some external second level cache such as Infinispan, EHCache etc.

查询缓存由 Hibernate 内部提供,而对于二级缓存,您必须选择一些外部二级缓存,例如 Infinispan、EHCache 等。

enter image description here

在此处输入图片说明

回答by Mudit bhaintwal

Second level cache has hash table like structure internally to hold the data. The Key here will be the identifier of the entity and value will be dehydrated values of the entity. To get the data out of this L2 cache, you must have a Key i.e. identifier of the entity. So clearly you can use it with methods where you are fetching entity by id.

二级缓存在内部具有类似哈希表的结构来保存数据。这里的 Key 是实体的标识符,value 是实体的脱水值。要从这个 L2 缓存中获取数据,您必须有一个 Key,即实体的标识符。很明显,您可以将它与通过 id 获取实体的方法一起使用。

This scenario changes when you have query_cache also enabled with L2 cache. Query cache stores the query and it's corresponding resultset entities' ids. Now even if you are not fetching by id (using JPQL or HQL OR queryDsl), hibernate checks if the same query is fired earlier and if yes get the list of ids from the query cache. After that returns the entities from L2 cache corresponding to same ids.

当您同时使用 L2 缓存启用 query_cache 时,这种情况会发生变化。查询缓存存储查询及其对应的结果集实体的 id。现在,即使您不是通过 id 获取(使用 JPQL 或 HQL OR queryDsl),hibernate 也会检查是否之前触发了相同的查询,如果是,则从查询缓存中获取 id 列表。之后从 L2 缓存中返回对应于相同 id 的实体。

回答by Ritesh Kaushik

We need to explicitly put @Cache(usage=CacheConcurrencyStrategy.<VALUE>)on the collections and @Cacheableon the corresponding collection class. There is a very good explanation on hibernate second level cache here.

我们需要显式地放置@Cache(usage=CacheConcurrencyStrategy.<VALUE>)集合和@Cacheable相应的集合类。有关于Hibernate的二级缓存很好的解释在这里