Mybatis二级缓存

Posted on 2020-09-10 11:38  三月老泉  阅读(176)  评论(0编辑  收藏  举报

转: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:代表的是缓存收回策略,有一下策略:

    1. LRU, 最近最少使用的,移除最长时间不用的对象。
    2. FIFO,先进先出,按对象进入缓存的顺序来移除他们
    3. SOFT, 软引用,移除基于垃圾回收器状态和软引用规则的对象。
    4. WEAK,若引用,更积极的移除基于垃圾收集器状态和若引用规则的对象
  • flushInterval:刷新间隔时间,单位为毫秒,默认是当sql执行的时候才回去刷新。

  • size:引用数目,一个正整数,代表缓存最多可以存储多少对象,不宜设置过大,过大会造成内存溢出。

  • readOnly:

         true:只读:mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。mybatis为了加快获取数据,直接就会将数据在缓存中的引用交给用户 。不安全,速度快    
         false:读写(默认):mybatis觉得获取的数据可能会被修改。mybatis会利用序列化&反序列化的技术克隆一份新的数据给你。安全,速度相对慢

 
 实例:

一、创建一个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>