1、MyBatis缓存概述
1.1、什么是MyBatis缓存
像大多数的持久化框架一样,MyBatis 也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能。
1.2、MyBatis缓存分类
MyBatis 中缓存分为一级缓存,二级缓存。
默认情况下,只有一级缓存(SqlSession级别的缓存,也称为本地缓存)开启。
二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
为了提高扩展性。MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
1.3、前期准备
创建一个新的项目mb004
2、MyBatis一级缓存
一级缓存是SqlSession,只要SqlSession没有flush和close,SqlSession都是存在的。
2.1、一级缓存验证
完成学生信息查询
代码语言:javascript复制@Test
public void findById(){
Students students=studentsDao.findById(2);
System.out.println("第一次查询:" students);
Students students1=studentsDao.findById(2);
System.out.println("第二次查询:" students1);
}
2.2、一级缓存业务
一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。
代码语言:javascript复制 @Test
public void findById(){
Students students=studentsDao.findById(2);
System.out.println("第一次查询:" students);
students.setSname("你好");
students.setSage(19);
studentsDao.updateStudents(students);
Students students1=studentsDao.findById(2);
System.out.println("第二次查询:" students1);
System.out.println(students==students1);
}
执行步骤:
第一次查询id为2的学生信息,先去缓存中找,如果没有去查询数据库
修改学生信息,执行了一次commit,一级缓存清理
第二次查询id为2的学生信息,也去缓存中找,如果没有去查询数据库
2.3、一级缓存清理
clearCache():清除一级缓存
代码语言:javascript复制 @Test
public void findById(){
Students students=studentsDao.findById(2);
System.out.println("第一次查询:" students);
session.clearCache();//清除一级缓存的方法
Students students1=studentsDao.findById(2);
System.out.println("第二次查询:" students1);
System.out.println(students==students1);
}
3、MyBatis二级缓存
二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。
3.1、二级缓存开启
3.1.1、配置SqlMapConfig.xml
代码语言:javascript复制<settings>
<!-- 开启二级缓存的支持 --> <setting name="cacheEnabled" value="true"/>
</settings>
cacheEnabled 默认值为 true。为 true 代表开启二级缓存;为false 代表不开启二级缓存。
3.1.2、配置ISudentsDao.xml
代码语言:javascript复制格式:
<cache></cache>
格式:
useCache属性:true|false
useCache=”true”代表当前要使用二级缓存,如果不使用二级缓存可以设置为 false。
代码语言:javascript复制<?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.tyschool.mb004.students.dao.IStudentsDao">
<cache></cache>
<select id="findById" resultType="Students" parameterType="int" useCache="true">
select * from students where sid=#{sid}
</select>
<update id="updateStudents" parameterType="Students">
update students set sname=#{sname},ssex=#{ssex},sage=#{sage},cid=#{cid} where sid=#{sid}
</update>
</mapper>
注意:
配置中大部分属性都有默认配置,不用配置也可使用。
代码语言:javascript复制<cache eviction="LRU" flushInterval="10000" size="1024" readOnly="true"/>
的属性:
**eviction:**代表的是缓存收回策略,有一下策略:
LRU, 最近最少使用的,移除最长时间不用的对象。
FIFO,先进先出,按对象进入缓存的顺序来移除他们
SOFT, 软引用,移除基于垃圾回收器状态和软引用规则的对象。
WEAK,若引用,更积极的移除基于垃圾收集器状态和若引用规则的对象
**flushInterval:**刷新间隔时间,单位为毫秒,默认是当sql执行的时候才回去刷新。
**size:**引用数目,一个正整数,代表缓存最多可以存储多少对象,不宜设置过大,过大会造成内存溢出。
**readOnly:**只读,意味着缓存数据只能读取,不能修改,这样设置的好处是我们可以快速读取缓存,去诶但是我们没有办法修改缓存。默认值为false,不允许我们修改。
3.2、二级缓存测试
代码语言:javascript复制@Test
public void findById(){
session=factory.openSession();
studentsDao=session.getMapper(IStudentsDao.class);
Students students=studentsDao.findById(2);
System.out.println("第一次查询:" students);
session.close();
session=factory.openSession();
studentsDao=session.getMapper(IStudentsDao.class);
Students students1=studentsDao.findById(2);
System.out.println("第二次查询:" students1);
System.out.println(students==students1);
session.close();
}