转:https://www.cnblogs.com/happyflyingpig/p/7739749.html
Mybatis二级缓存
MyBatis对缓存提供支持,但在没有配置的默认情况下,它只开启一级缓存(一级缓存是相对于同一个SqlSession而言)。
在sql和参数完全一样的情况下,使用同一个SqlSession对象调用同一个Mapper的方法,只会执行一次Sql,因为使用SqlSession第一次查询后,MyBatis会将其放在缓存中,以后在查询的时候,如果没有申明需要刷新,并且缓存没有超时的情况下,SqlSession都只会取出当前缓存的数据,而不会再次发送sql到数据库。
但如果不是一个SqlSession对象,因为不同SqlSession都是相互隔离的,所以一级缓存失效。
二级缓存是在SqlSessionFactory层面上的缓存,默认不开启,开启的话只需要在映射XML文件中配置,开启缓存即可
<cache eviction="LRU" flushInterval="60000" size="1024" readOnly="true"/>
这句配置中大部分属性都有默认配置,不用配置也可使用。
讨论一下<cache />的属性:
-
eviction:代表的是缓存收回策略,有一下策略:
- LRU, 最近最少使用的,移除最长时间不用的对象。
- FIFO,先进先出,按对象进入缓存的顺序来移除他们
- SOFT, 软引用,移除基于垃圾回收器状态和软引用规则的对象。
- WEAK,若引用,更积极的移除基于垃圾收集器状态和若引用规则的对象
-
flushInterval:刷新间隔时间,单位为毫秒,默认是当sql执行的时候才回去刷新。
-
size:引用数目,一个正整数,代表缓存最多可以存储多少对象,不宜设置过大,过大会造成内存溢出。
-
readOnly:
一、创建一个POJO Bean并序列化
@data
public class Student implements Serializable{ private String id; private String name; private int age; private Gender gender; private List<Teacher> teachers;
}
二、在映射文件中开启二级缓存
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yihaomen.mybatis.dao.StudentMapper">
<!--开启本mapper的namespace下的二级缓存-->
<!--
eviction:代表的是缓存回收策略,目前MyBatis提供以下策略。
(1) LRU,最近最少使用的,一处最长时间不用的对象
(2) FIFO,先进先出,按对象进入缓存的顺序来移除他们
(3) SOFT,软引用,移除基于垃圾回收器状态和软引用规则的对象
(4) WEAK,弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象。这里采用的是LRU,
移除最长时间不用的对形象
flushInterval:刷新间隔时间,单位为毫秒,这里配置的是100秒刷新,如果你不配置它,那么当
SQL被执行的时候才会去刷新缓存。
size:引用数目,一个正整数,代表缓存最多可以存储多少个对象,不宜设置过大。设置过大会导致内存溢出。
这里配置的是1024个对象
readOnly:只读,意味着缓存数据只能读取而不能修改,这样设置的好处是我们可以快速读取缓存,缺点是我们没有
办法修改缓存,他的默认值是false,不允许我们修改
-->
<cache eviction="LRU" flushInterval="100000" readOnly="true" size="1024"/>
<resultMap id="studentMap" type="Student">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="age" column="age" />
<result property="gender" column="gender" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler" />
</resultMap>
<resultMap id="collectionMap" type="Student" extends="studentMap">
<collection property="teachers" ofType="Teacher">
<id property="id" column="teach_id" />
<result property="name" column="tname"/>
<result property="gender" column="tgender" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
<result property="subject" column="tsubject" typeHandler="org.apache.ibatis.type.EnumTypeHandler"/>
<result property="degree" column="tdegree" javaType="string" jdbcType="VARCHAR"/>
</collection>
</resultMap>
<select id="selectStudents" resultMap="collectionMap">
SELECT
s.id, s.name, s.gender, t.id teach_id, t.name tname, t.gender tgender, t.subject tsubject, t.degree tdegree
FROM
student s
LEFT JOIN
stu_teach_rel str
ON
s.id = str.stu_id
LEFT JOIN
teacher t
ON
t.id = str.teach_id
</select>
<!--可以通过设置useCache来规定这个sql是否开启缓存,ture是开启,false是关闭-->
<select id="selectAllStudents" resultMap="studentMap" useCache="true">
SELECT id, name, age FROM student
</select>
<!--刷新二级缓存
<select id="selectAllStudents" resultMap="studentMap" flushCache="true">
SELECT id, name, age FROM student
</select>
-->
</mapper>
三、在 mybatis-config.xml中开启二级缓存
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--这个配置使全局的映射器(二级缓存)启用或禁用缓存-->
<setting name="cacheEnabled" value="true" />
.....
</settings>
....
</configuration>