一级缓存
概述
sqlsession级别的缓存
在操作数据库时,需要构造sqlsession对象,<br>在对象中有一个数据结构(HashMap)用于存储缓存数据<br>
不同的sqlsession之间的缓存区域是互相不影响的。
实现原理解析
第一次发起查询sql查询用户id为1的用户,先去找缓存中是否有id为1的用户,<br>如果没有,再去数据库查询用户信息。得到用户信息,将用户信息存储到一级缓存中。<br>
如果sqlsession执行了commit操作(插入,更新,删除),会清空sqlsession中的一级缓存,避免脏读。
第二次发起查询id为1的用户,缓存中如果找到了,直接从缓存中获取用户信息
mybatis默认支持并开启一级缓存。
案例
必须配置日志,要不看不见<br>
总结
一级缓存失效
sqlSession不同
当sqlSession对象相同的时候,查询的条件不同,查询的结果不同,<br>原因是第一次查询时候一级缓存中没有第二次查询所需要的数据<br>
当sqlSession对象相同,两次查询之间进行了插入的操作<br>
当sqlSession对象相同,手动清除了一级缓存中的数据
二级缓存
概述
二级缓存是mapper级别的缓存
多个sqlsession去操作同一个mapper的sql语句,<br>多个sqlsession可以共用二级缓存,<br>所得到的数据会存在二级缓存区域。<br>
二级缓存是跨sqlsession的
二级缓存相比一级缓存的范围更大(按namespace来划分),<br>多个sqlsession可以共享一个二级缓存。<br>
案例
开启二级缓存
<settings> <br> <!--开启二级缓存--> <br> <setting name="cacheEnabled" value="true"/> <br></settings> <!-- 需要将映射的javabean类实现序列化 --><br>
开启本Mapper的namespace下的二级缓存
<cache eviction="LRU" flushInterval="100000"/><br>
案例 cache 属性的简介
eviction:回收策略(缓存满了的淘汰机制)
LRU(Least Recently Used),最近最少使用的,最长时间不用的对象
FIFO(First In First Out),先进先出,按对象进入缓存的顺序来移除他们
SOFT,软引用,移除基于垃圾回收器状态和软引用规则的对象
WEAK,弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象。<br>这里采用的是LRU,移除最长时间不用的对形象<br>
flushInterval:刷新间隔时间,单位为毫秒
这里配置的是100秒刷新,如果你不配置它,那么当SQL被执行的时候才会去刷新缓存。
size:引用数目<br>
一个正整数,代表缓存最多可以存储多少个对象,不宜设置过大。<br>设置过大会导致内存溢出。这里配置的是1024个对象<br>
readOnly:只读<br>
意味着缓存数据只能读取而不能修改,这样设置的好处是我们可以快速读取缓存,<br>缺点是我们没有办法修改缓存,他的默认值是false,不允许我们修改。<br>
禁用二级缓存
在statement中可以设置useCache=false,禁用当前select语句的二级缓存,默认情况为true
<select id="getStudentById" parameterType="java.lang.Integer" resultType="Student" useCache="false">
在实际开发中,针对每次查询都需要最新的数据sql,要设置为useCache="false" ,禁用二级缓存
刷新缓存(清空缓存)
flushCache标签
<select id="getStudentById" parameterType="java.lang.Integer" resultType="Student" flushCache="true">
一般下执行完commit操作都需要刷新缓存,flushCache="true 表示刷新缓存,可以避免脏读
二级缓存应用场景
对于访问多的查询请求并且用户对查询结果实时性要求不高的情况下,<br>可采用mybatis二级缓存,降低数据库访问量,提高访问速度,<br>如电话账单查询,根据需求设置相应的flushInterval:刷新间隔时间,<br>比如三十分钟,24小时等。<br>
二级缓存局限性
mybatis二级缓存对细粒度的数据级别的缓存实现不好,<br>比如如下需求:对商品信息进行缓存,由于商品信息查询访问量大,<br>但是要求用户每次都能查询最新的商品信息,<br>此时如果使用mybatis的二级缓存就无法实现当一个商品变化时只刷新该商品的缓存信息而不刷新其它商品的信息,<br>因为mybaits的二级缓存区域以mapper为单位划分,<br>当一个商品信息变化会将所有商品信息的缓存数据全部清空。<br>解决此类问题需要在业务层根据需求对数据有针对性缓存。<br>