Hibernate二级缓存与查询缓存的组合探究

0. 前言

          由于对 Hibernate 的二级缓存和查询缓存的区别不了解,也不知道它们起什么作用。于是动手做了一些实验,对它们的组合使用有了一个表面的认识。

1. 前提

          1)  不使用一级缓存( Session 级别)的情况。因为大部分 apisession 的操作都进行 n 层封装,用完 sessionclose ,一般很少使用到一级缓存。

          2)  开启 hibernate.show_sql=true ,根据 sql 的是否输出来判断是否访问了数据库。

2. 基础 2.1. 二级缓存

          二级缓存是 SessionFactory 级别的全局缓存,它为每个类(或集合)提供缓存。凡是调用二级缓存的查询方法都会从中受益,比如 load,list,iterate 等方法(注意, getfind 不使用缓存,直接访问数据库)。

          开启条件:

          1)hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider (这里指定了 ehcache

          2)hbm.xml 配置 <cache usage="read-write"/>

          3)ehcache.xml 定义该类的 cache

          简单地说,二级缓存是用来保存类对象的,并且填充它的所有属性值。

2.2. 查询缓存

          查询缓存保存的是查询方法( listiterate 等)查询的 sql 语句和结果集,跟 load 这种装载对象的方法没有关系。也就是说,使用 load 方法,查询缓存不理睬。

          并且这个结果集只是对象 id 列表,对象的其他属性值不保存。例如, list 执行的时候,先根据查询缓存中的 sql 语句,获取对象 id 列表,然后再 load(id) 来取对象。

          开启条件:

          1) hibernate.cache.use_query_cache=true

          2)Query 或者 Criteria 使用时,设置 setCacheable(true)

          简单地说,查询缓存是用来保存 sql 执行后获取的对象 id 列表。下一次执行同一条 sql 时,可直接从查询缓存中获取到对象 id 列表。

3. 实验

          以下对最常用的 loadlist 方法进行二级缓存和查询缓存的组合测试。 loadlist 执行的结果,都是返回同一个对象。

3.1. 四种组合

          二级缓存和查询缓存的组合,根据开启和不开启两种情况,划分为四种组合( √代表开启,×代表不开启 ):

         

组合

二级缓存

查询缓存

1

×

2

×

3

4

×

×

3.2.load 实验

          对同一个 id ,使用 load 执行两次,观察 sql 的输出现象,也就是判断第二次 load 是否访问了数据库。其中 √代表输出,×代表未输出:

 

组合

第一次 sql

第二次 sql

结论

1

×

与查询缓存无关

2

3

×

4

 

          当开启了二级缓存, load 先从缓存中获取对象,于是组合 13 的第二次 sql 都未输出,即第二次查询没有访问数据库。

          当没有开启二级缓存, load 总是直接访问数据库的。也证明了,查询缓存与 load 方法无关。

3.3.list 实验

          对同一条 sql 语句,使用 list 执行两次,观察 sql 的输出现象。其中 √代表输出,×代表未输出:

 

组合

第一次 sql

第二次 sql

结论

1

list 每次访问数据库都会填充二级缓存,相当于二级缓存无效

2

√(不一样)

这两条 sql 语句不一样,第一条是 list 的,第二条是 load

3

×

 

4

 

 

          对组合 1 现象的解释:

          当没有开启查询缓存时, list 每次都会直接访问数据库,然后把二级缓存给重新填充。也就是说, list 在不开启查询缓存的情况下,根本就没有利用到二级缓存的好处。

          对组合 2 现象的解释:

          第一条 sqllist 正常访问数据库的,但第二次执行 list 时,由于有了查询缓存,直接根据第一条 sql 获取对象的 id ,此时由于没有开启二级缓存, load(id) 后也没法从二级缓存中拿数据,只好再次访问数据库。但在组合 3 中, load(id) 可以从二级缓存中拿数据,所以不用访问数据库。

3.4. 小结

         loadlist 方法中,使用二级缓存和查询缓存的不同组合,效果出现了差别。特别强调的是,由于很多操作是基于 list 的,如果没有开启查询缓存,根本就使用不了二级缓存的数据,也就提高不了性能了(但是 iterate 可以使用到二级缓存)。

          另外,从表格中可以看出来,同时开启二级缓存和查询缓存,效果是最好的,第二次查询都不需要访问数据库。

4. 维护

          当存在除 hibernate 之外的改变数据库数据的方式时,维护二级缓存和查询缓存是很麻烦的。比如使用 jdbc 或者第三方系统修改了数据库, hibernate 都不知道,也就没法自行维护缓存了。这时需要手动维护,如果存在第三方系统,还需要让第三方系统发消息通知 hibernate

          维护手段也就是 evict (清除某个类的二级缓存)和 evictQuery (清除查询缓存)。针对数据修改的三种形式,分别维护:

          1)insertevictQuery

          2)deleteevictevictQuery

          3)updateevict

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值