Hibernate一级缓存与查询缓存

Hibernate一级缓存与查询缓存,hibernate,query-cache,first-level-cache,Hibernate,Query Cache,First Level Cache,第一级缓存与hibernate中的查询缓存不同吗?我看到一些文章提到了第一级缓存和查询缓存,所以我感到困惑。第一级缓存默认是启用的,并且是基于会话的。默认情况下,查询缓存未启用,跨多个会话共享,并且应始终与二级缓存一起使用 要启用查询缓存,应使用以下属性: hibernate.cache.use_second_level_cache=true hibernate.cache.use_query_cache=org.hibernate.cache.EhCacheProvider hibernate

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

第一级缓存默认是启用的,并且是基于会话的。默认情况下,查询缓存未启用,跨多个会话共享,并且应始终与二级缓存一起使用

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

hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=org.hibernate.cache.EhCacheProvider
hibernate.cache.use_query_cache=true
是的,是不同的东西。 正如Lee Chee Kiam所说,一级缓存在默认情况下是启用的,您不能禁用它。 基本上,它是Hibernate第一次放置获取的实体的地方,因此对同一对象的第二次查询不会实例化新对象,甚至可以避免按ID进行查询。这是一个示例

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

查询缓存严格地与实体相关,它在搜索条件和满足特定查询筛选器(从)的实体之间绘制关联。 查询缓存仅将查询的原始结果作为主键保存,在hibernate中是id它不能容纳实际的水合物体

查询缓存是如何工作的

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

session.createCriteria(Person.class)
    .add( Restrictions.eq("firstName", "Joey")
    ).setCacheable(true);
查询缓存在概念上类似于哈希映射,其中键由查询文本和参数值组成,值是与查询匹配的实体Id的列表

*----------------------------------------------------------*
|                       Query Cache                        |                     
|----------------------------------------------------------|
| ["from Person where firstName=?", ["Joey"] ] -> [1, 2] ] |
*----------------------------------------------------------*
因此,下一次执行相同的条件查询时,Hibernate将查看该哈希映射,并确定id为1和2的人员符合限制。 在这种情况下,您可以避免查询的成本(在这种情况下几乎为零,但可能是一个昂贵的带有连接的查询,等等),但是您仍然需要访问数据库来查询Person(现在是通过id,这是非常快的),以构造Person对象。 查询缓存经常与二级缓存一起使用,二级缓存需要第三方实现,如Ehcache或infinispan

第二级缓存存储实体数据,但不存储实体本身。数据以“脱水”格式存储,该格式类似于哈希映射,其中键是实体Id,值是基本值列表。 下面是一个关于二级缓存内容外观的示例:

*-----------------------------------------*
|          Person Data Cache              |
|-----------------------------------------|
| 1 -> [ "Joey" , "Q" , "Public" , null ] |
| 2 -> [ "Joey" , "D" , "Public" ,  1   ] |
| 3 -> [ "Sara" , "N" , "Public" ,  1   ] |
*-----------------------------------------*
因此,查询缓存将为我们提供ID1和ID2,然后Hibernate将使用第二级缓存中的原始数据构造对象,该缓存对应于ID1和ID2的人员

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

这里有一些解释,你也应该读一下

*-----------------------------------------*
|          Person Data Cache              |
|-----------------------------------------|
| 1 -> [ "Joey" , "Q" , "Public" , null ] |
| 2 -> [ "Joey" , "D" , "Public" ,  1   ] |
| 3 -> [ "Sara" , "N" , "Public" ,  1   ] |
*-----------------------------------------*