与这个问题有关
前提:
这些是我的假设,基于我的阅读、经验和理解,它们可能是错误的,如果是,请发表评论,我将编辑问题。
- 查询缓存主要与二级缓存一起使用
- 查询缓存缓存查询+参数的标识符结果
- 如果数据库被更改并且它没有反映到缓存中,查询缓存是有风险的
问题:
我有一个不在二级缓存中的对象。由于一些糟糕的编程或其他限制,加载对象的代码在同一个休眠会话中被多次调用。检索使用 HQL 查找查询,例如
hibernateTemplate.find("from Foo f where f.bar > ?", bar);
在添加查询缓存之前,如果上面的代码在同一个Hibernate Session中被调用N次,那么数据库有N次命中
然后我想看看如果我添加查询缓存会发生什么:
Query query = session.createQuery("from Foo f where f.bar > ?");
query.setCacheable(true);
query.setParameter(bar);
query.list();
当我添加查询缓存时,我注意到在同一个会话期间,休眠不再访问数据库 N 次,每个会话只有一次。
- 所以我的第一个假设是 Hibernate 首先在 Session Cache 中搜索,然后在 2nd Level Cache 中搜索。这个假设正确吗?
- 我还假设如果
Foo
不在二级缓存中的对象 () 在数据库中被更改,那么跨会话范围的查询缓存将返回错误的标识符,从而返回错误的对象。那是对的吗? - 是否可以肯定地说,即使对于非 2L 缓存对象,对包含不可变信息的查询使用查询缓存是一种好习惯?(例如一个查询,它的 where 子句包含一个总是返回相同结果的条件,例如“select p.ser_num where p.id = ?” 当 ser_num 和 id 对一旦创建就不会改变)
顺便说一句,在相关问题中声称查询缓存不适用于会话缓存范围。我是否误解了该声明或其他任何内容?