1

我有一个用例做分页。当然,当用户四处走动时,它会再次点击相同的页面。我已经有了页面的主键集。

此外,类似的搜索将命中一些已经加载到一级和二级缓存中的实体。

当我对一批主键进行查询时,Hibernate 不够聪明,无法避免在缓存命中时调用数据库。所以我想通过首先对一级和二级缓存使用低级 API 来解决这个问题。

因此,例如,如果我想加载以下主键:1、2、3

如果 2 已经在一级缓存中,我只想用 1 和 3 调用数据库。

所以我正在寻找一个像 session.peek(MyEntity.class, 2) 这样的 API,如果没有找到 peek 函数将返回 null ,或者如果在一级或二级缓存中找到实体,则返回实体。

如果存在的话,我可以从更低级别的 API 创建这个函数。

4

1 回答 1

1

实际上,这已经在 Hibernate 中实现了,它被称为查询缓存。下面是它的工作原理:

  1. 每次访问列表的第一页时,Hibernate 都会将第一页中的所有实体放入二级缓存(ID -> 实体)

  2. 此外,Hibernate 会将原始 ID 放入所谓的查询缓存中。此缓存中的一个键是查询 + 查询参数(哪个页面和多少项)。

  3. 下次用户访问同一页面时,Hibernate 首先检查查询缓存。如果它命中缓存(相同的查询已经在前一段时间使用相同的参数执行过),它会返回当时返回的记录的 ID。

  4. 然后它使用二级缓存来获取这些记录而不是访问数据库。当然,如果某些记录不在 L2 中,Hibernate 会在您不注意的情况下自动获取它。

听起来正是您想要实现的目标。不幸的是,调整和有效使用查询缓存非常困难,而且很容易错误配置,从而降低整体系统性能。

此外,默认情况下不启用查询缓存。即使是这样,您也必须明确定义要缓存的查询。

于 2012-07-17T13:21:49.230 回答