查询缓存:我们前面提到查询缓存(Query Cache)依赖二级缓存,这到底是怎么回事呢?我看看二级缓存策略的一般过程:
(1) Hibernate进行条件查询的时候,总是发出一条select * from XXX where …(XXX为 表名,类似的语句下文统称Select SQL)这样的SQL语句查询数据库,一次获得所有的符合条件的数据对象。
(2) 把获得的所有数据对象根据ID放入到第二级缓存中。
(3) 当Hibernate根据ID访问数据对象的时候,首先从内部缓存中查找,如果在内部缓存中查不到就配置二级缓存,从二级缓存中查;如果还查不到,再查询数据库,把结果按照ID放入到缓存。
(4)添加数据、删除、更新操作时,同时更新二级缓存。这就是Hibernate做批处理的时候效率不高的原因,原来是要维护二级缓存消耗大量时间的缘故。
我们看到这个过程后,可以明显的发现什么?那就是Hibernate的二级缓存策略是针对ID查询的策略,和对象ID密切相关,那么对于条件查询就怎么适用了。对于这种情况的存在,Hibernate引入了“查询缓存”在一定程度上缓解这个问题。
那么我们先来看看我们为什么使用查询缓存?首先我们来思考一个问题,假如我们对数据表Student进行查询操作,查找age>20的所有学生信息,然后纳入二级缓存;第二次我们的查询条件变了,查找age>15的所有学生信息,显然第一次查询的结果完全满足第二次查询的条件,但并不是满足条件的全部数据。这样的话,我们就要再做一次查询得到全部数据才行。再想想,如果我们执行的是相同的条件语句,那么是不是可以利用之前的结果集呢?
Hibernate就是为了解决这个问题的而引入Query Cache的。
查询缓存策略的一般过程如下:
(1)Query Cache保存了之前查询的执行过的Select SQL,以及结果集等信息,组成一个Query Key。(2)当再次遇到查询请求的时候,就会根据Query Key 从Query Cache找,找到就返回。但 是两次查询之间,数据表发生数据变动的话,Hibernate就会自动清除Query Cache中对应的Query Key。
我们从查询缓存的策略中可以看出,Query Cache只是在特定的条件下才会发挥作用,而且要求相当严格:
(1)完全相同的Select SQL重复执行。
(2)重复执行期间,Query Key对应的数据表不能有数据变动(比如添、删、改操作)
为了启用Query Cache,我们需要在hibernate.cfg.xml中进行配置,参考配置如下(只列出核心配置项):
hibernate.cache.user_query_cache>true
应用程序中必须在查询执行之前,将Query.Cacheable设置为true,而且每次都应该这样。比如: ……… Query query=session.createQuery(hql).setInteger(0.15); query.setCacheable(true); ………
4:编后语
关于Hibernate缓存的讨论就告一段落了,在实际开发中,运用好缓存可以让你的系统性能得到良好的提升。可缓存也有它的局限性,什么情况用什么情况不用,都要结合实际情况来考量。如果违背了相关的缓存机制,可能会得到负面效果,所以充分考虑实际情况来灵活运用缓存并发挥它的优势,这是我们需要做得更多的。
本文转自
http://www.qqread.com/java/2007/11/u380944_5.html