前言
Mybatis缓存分为一级缓存和二级缓存。一级缓存的作用域是在sqlSession,即一次会话,从开始到关闭。二级缓存的作用域是每个Mapper.xml。默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。要启用二级缓存,只需要在SQL映射文件中添加一行:<cache/>。[Mybatis官方文档-缓存](https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache)
一、在pom.xml中添加Ehcache缓存包。
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.1.0</version>
</dependency>
二、在mybatis-config中显示开启缓存。
<setting name="cacheEnabled" value="true"/>
三、在Mapper.xml中配置缓存信息。
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
四、创建学生实体类。
@Data
public class Student implements Serializable {
private int id;
private String name;
private int tid;
}
五、创建学生接口。
List<Student> getStudentList(Map map);
六、创建StudentMapper.xml。
<?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.zhy.dao.StudentMapper">
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
<select id="getStudentList" parameterType="map" resultType="com.zhy.entity.Student" useCache="true">
SELECT id,name,tid FROM student
<where>
<foreach item="id" collection="ids" open="(" close=")" separator="or">
id=#{id}
</foreach>
</where>
</select>
</mapper>
七、测试类。
@Test
public void test01() {
SqlSession sqlSession = MyUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
HashMap<String, List> map = new HashMap<>();
ArrayList<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
ids.add(3);
map.put("ids", ids);
List<Student> studentList = mapper.getStudentList(map);
for (Student student : studentList) {
System.out.println(student);
}
sqlSession.close();
SqlSession sqlSession1 = MyUtils.getSqlSession();
StudentMapper mapper1 = sqlSession1.getMapper(StudentMapper.class);
List<Student> studentList1 = mapper1.getStudentList(map);
for (Student student : studentList1) {
System.out.println(student);
}
sqlSession1.close();
}
八、二级缓存。
缓存只作用于cache标签所在的映射文件中的语句。
- 映射语句文件中的所有 select 语句的结果将会被缓存。
- 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
- 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
- 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
- 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
- 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。