Era*_*dan 10 hibernate second-level-cache session-cache query-cache
与此问题相关
前提:
这些是我的假设,根据我的阅读,经验和理解,他们可能是错的,如果他们是,请评论,我会编辑问题.
题:
我有一个不在二级缓存中的对象.由于一些糟糕的编程或其他约束,加载对象的代码在同一个休眠会话中被多次调用.回顾是使用HQL查找查询,例如
hibernateTemplate.find("from Foo f where f.bar > ?", bar);
Run Code Online (Sandbox Code Playgroud)
在添加查询缓存之前,如果上述代码在同一个Hibernate会话中被调用了N次,那么数据库就会有N次命中
然后我想看看如果添加查询缓存会发生什么:
Query query = session.createQuery("from Foo f where f.bar > ?");
query.setCacheable(true);
query.setParameter(bar);
query.list();
Run Code Online (Sandbox Code Playgroud)
当我添加查询缓存时,我注意到在同一个会话期间,hibernate不会再次访问数据库N次,每个会话只有一次.
Foo不在第二级缓存中的object()在数据库中被更改,那么查询缓存(跨会话范围)将返回错误的标识符,从而返回错误的对象.那是对的吗?顺便说一下,在相关问题中声称查询缓存不适用于会话缓存范围.我想知道这个说法或其他什么吗?
查询缓存是特定类型的二级缓存.您所谓的二级缓存我更喜欢称之为"对象缓存".
评论你的假设:
- 查询缓存主要与二级缓存(又称对象缓存)一起使用.
查询缓存仅将查询的原始结果保存为主键,在hibernate中,id为.它不能容纳实际的水合物.这是有道理的,因为当您使用jdbc执行查询时,它实际上只会在您迭代ResultSet时返回水合(填充)对象.声明不一定正确.如果查询非常复杂并因此需要很长时间才能运行,那么通过使用查询缓存,您将节省该时间.您不会通过使用查询缓存来节省从数据库加载对象所需的时间.
- 如果数据库已更改,则查询缓存存在风险,并且未将其反映到缓存中
这是事实,但它并不是查询缓存所特有的,对于您所说的二级缓存也是如此,但通常称为对象缓存.
所以我的第一个假设是Hibernate首先在Session Cache中搜索,然后在2nd Level Cache中搜索.这个假设是否正确?
是的,在加载对象时,这就是行为.
我还假设如果在数据库中更改了不在第二级缓存中的对象(Foo),那么查询缓存(跨会话范围)将返回错误的标识符,从而返回错误的对象.那是对的吗?
是的,对象缓存和查询缓存都会受到影响.如果在不经过休眠的情况下更改数据库,这只是一个问题.您可以通过设置查询缓存的超时来减轻此影响.
那么,对于包含不可变信息的查询,即使对于非2L缓存对象,使用查询缓存是否安全可行?(例如,其where子句包含将始终返回相同结果的条件的查询,例如,当ser_num和id对在创建后不更改时,"select p.ser_num where p.id =?")
对于这些类型的对象,没有理由不同时使用对象缓存和查询缓存.
是的,查询缓存在会话级别也称为1级缓存不起作用.因此,当您再次执行查询时,它再次命中数据库.它不会将查询的结果(id set)放入会话缓存中.
| 归档时间: |
|
| 查看次数: |
6470 次 |
| 最近记录: |