设置缓存的目的就是为了提高查询访问速度。mybatis根据缓冲区的作用域划分为两种:一级查询缓存和二级查询缓存
基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空。也就是当SqlSession结束后,该SqlSession中的一级缓存也就不存在了。mybatis默认的一级缓存是开启状态并且不能关闭。
一、证明一级缓存的存在性
在这里使用最简单的例子只是实现了增删改查操作。
修改测试类MyTest
//根据id号选出学生
@Test
public void testselectStudentById() {
Student student = dao.selectStudentById(24);
System.out.println(student);
Student student2 = dao.selectStudentById(24);
System.out.println(student2);
}
在这里,查询了两次id=24的student。现在来查看后台的打印结果。
我们看到,控制太出现的结果是:两次输出,但是只是执行了一次查询。说明第二次查询是从缓存中取得的数据。
二、问题:第二次查询根据什么获得的缓存中的数据?
其实,一级缓存其缓存的是相同Sql映射的id的查询结果,而不是相同sql语句的查询结果。因为mybatis内部对于查询缓存,无论是一级缓存还是二级缓存,其底层都是使用一个HashMap实现:key是sql的id,value是从数据库中查询出的结果。
要注意:在这里的id不是每一个Student的id,而是这个Sql的id。也就是Mapper文件中的id
验证问题:
1、此时修改映射文件:
2、修改Dao接口
public interface IStudentDao {
Student selectStudentById(int id);
Student selectStudentById2(int id);
}
3、修改测试类
//根据id号选出学生
@Test
public void testselectStudentById() {
//第一次查询
Student student = dao.selectStudentById(24);
System.out.println(student);
//第二次查询
Student student2 = dao.selectStudentById2(24);
System.out.println(student2);
}
查看结果:
三、增删改对一级缓存的影响
增删改操作,无论其是否进行sqlSession.commit(),都会清除一级查询缓存
验证增删改操作的影响
1、修改测试类
//根据id号选出学生
@Test
public void testselectStudentById() {
//第一次查询
Student student = dao.selectStudentById(24);
System.out.println(student);
//执行增删改操作
//dao.insertStudent(new Student());
dao.deleteStuById(30);
//dao.updateStu(new Student());
//第二次查询
Student student2 = dao.selectStudentById2(24);
System.out.println(student2);
}
2、查看运行结果
从运行结果来看,增删改操作确实是清除了一级缓存。