查询和缓存

经过大量的测试,查询和缓存之间的关系已经基本上清楚了。


1. 一次查询过后,结果集中的所有个体都会进入持久化上下文,也就是一级缓存中(如果打开了二级缓存,它们也同样会进入二级缓存)。这就是意味着后面的程序如果要load(不是查询)结果集中的任何一个对象都会从缓存中直接命中,不会生成任何SQL去Hit数据库。


2. 但是作为结果集的整体,在不使用查询缓存的前提下是不会被缓存的。举个例子:当执行一个得到某个班级所有学生的查询后,这个班级所有的学生实例会被加载并进行入缓存中。但是缓存并没有缓存“这些学生都是某一个班级”这层关系!因此,当再次执行这个查询时,依然会生成SQL再次访问数据库。想要缓存查询结果,在这个例子中也就是缓存 “这些学生都是某一个 班级”的这层关系,就得使用查询缓存!对于 查询缓存来说, 构成key的是:hql生成的sql、sql的参数、排序、分页信息等。

 

我想查询不会先从缓存中查找对象的根本原因在于,即使Hibernate发现缓存中有符合条件的 对象 ,但也无法证实这些对象是结果的全集。因为缓存中的数据只是一小部分,所以它必须要生成SQL去数据库中查询。

 

如果使用了“Query Cache”,对一个查询来说,对它的缓存是这样处理的:查询的结果集做为Value,放置于查询缓存的region中。注意:这里存在的并不是真正的结果集。因为查询出来的实例已经放入了二级缓存,所以查询缓存不会重复保存这些实例,而是只保存实例的ID。这一点在JPwH一书的15.4.2中作过解释。对于key,它应该是一个可以用来唯一标识这个查询的东西,在hibernate中查询缓存的key由 hql生成的sql、 sql的参数、排序、分页等信息组成, 通过它我们可以明确地区别不同的查询,以便某个查询在下一次重复执行时可以能过这个key直接命中结果集。

维护查询缓存会对系统带来一定的负荷,因为Hibernate必须追踪结果集中涉及的各类对象是否发生了改动,因为一旦它们发生了改动,这些对象就可能不再是结果集中一员,又或者原来不在结果集中的对象应该进入结果集,这样当前缓存的这个结果集就失效了,必须重新生成SQL进行查询。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Laurence 

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值