一级缓存默认自动开启,存在内存中(本地缓存)不能被关闭,可以调用clearCache()来清空本地缓存,或者改变缓存的作用域,是SqlSession级别的缓存
工作原理分析
当用户发起第一次查询team=1001的时候,先去缓存中查找是否有team=1001的对象;如果没有,继续向数据中发送查询语句,查询成功之后会将teamId=1001的结果存入缓存中;
当用户发起第2次查询team=1001的时候,先去缓存中查找是否有team=1001的对象,因为第一次查询成功之后已经存储到缓存中,此时可以直接从缓存中获取到该数据,意味着不需要再去向数据库发送查询语句。
如果SqlSession执行了commit(有增删改的操作),此时该SqlSession对应的缓存区域被整个清空,目的避免脏读。
前提:SqlSession未关闭。
Mybatis默认没有开启二级缓存,需要在setting全局参数中配置开启二级缓存。
二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace。
不同的sqlSession两次执行相同namespace下的sql语句参数相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。
1、在Mybatis框架的全局配置文件中开启二级缓存
<!--是否开启二级缓存,默认false-不开启, true:开启--> <setting name="cacheEnabled" value="true"/>
2、在需要二级缓存的Mapper中添加缓存标志
3、实体类必须实现Serializable接口
对于变化比较频繁的SQL,可以禁用二级缓存。
在开始了二级缓存的XML中对应的statement中设置useCache=false禁用当前Select语句的二级缓存,意味着该SQL语句每次只需都去查询数据库,不会查询缓存。
useCache默认值是true。对于一些很重要的数据尽不放在二级缓存中。
<cache> <property name="eviction" value="LRU"/><!--回收策略为LRU--> <property name="flushInterval" value="60000"/><!--自动刷新时间间隔为60S--> <property name="size" value="1024"/><!--最多缓存1024个引用对象--> <property name="readOnly" value="true"/><!--只读--> </cache> <!-- 属性介绍: 1.映射语句文件中的所有select语句将会被缓存; 2.映射语句文件中的所有CUD操作将会刷新缓存; 3.缓存会默认使用LRU(Least Recently Used)算法来收回; 3.1、LRU – 最近最少使用的:移除最长时间不被使用的对象。 3.2、FIFO – 先进先出:按对象进入缓存的顺序来移除它们。 3.3、SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。 3.4、WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。 4.缓存会根据指定的时间间隔来刷新(默认情况下没有刷新间隔,缓存仅仅调用语句时刷新); 5.缓存会存储列表集合或对象(无论查询方法返回什么),默认存储1024个对象。 6.缓存会被视为是read/write(可读/可写)的缓存,意味着检索对象不是共享的,而且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。 -->
如果想在命名空间中共享相同的缓存配置和实例,可以使用cache-ref 元素来引用另外一个缓存。
<cache-ref namespace="com.kkb.mapper.TeamMapper" /> //引用TeamMapper命名空间中的cache。