查询缓存是第二级缓存的一种特殊类型。您所说的二级缓存我更喜欢称之为“对象缓存”。
关于您的假设的评论:
- 查询缓存通常与第二级缓存(也称为对象缓存)一起很好。
查询缓存仅将查询的原始结果作为主键保存,在hibernate状态下为id。它不容纳实际的水合物体。这是有道理的,因为当您使用jdbc执行查询时,实际上只在迭代ResultSet时才给您水合(填充)的对象。该陈述不一定正确。如果查询非常复杂,因此运行时间很长,那么使用查询缓存可以节省时间。通过使用查询缓存,您将不会节省从数据库加载对象所花费的时间。
- 如果数据库已更改,并且没有反映到缓存中,则查询缓存存在风险
这是正确的,但查询缓存并不是唯一的,对于您所说的第二级缓存(通常称为对象缓存)也是如此。
因此,我的第一个假设是,Hibernate首先在会话缓存中搜索,然后在第二级缓存中搜索。 这个假设正确吗?
是的,当加载对象时,这就是行为。
我还假设,如果不在数据库中的二级缓存中的对象(Foo)已在数据库中更改,则跨会话范围的查询缓存将返回错误的标识符,从而返回错误的对象。 那是对的吗?
是的,对象缓存和查询缓存都将受到影响。仅当更改数据库而不通过hibernate时才需要考虑这一点。您可以通过设置查询缓存的超时来减轻这种影响。
那么可以肯定地说,即使对于非2L缓存的对象,也对包含不可变信息的查询使用查询缓存是一种好习惯吗?(例如,查询中的where子句包含始终返回相同结果的条件,例如,一旦创建后ser_num和id对不变,则“选择select
p.ser_num where p.id =?”)
对于这类对象,没有理由不同时使用对象缓存和查询缓存。
是的,查询缓存不适用于会话级别(也称为级别1缓存)。因此,当您再次执行查询时,它再次命中数据库的原因。它不会将查询的结果(标识集)放入会话缓存中。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)