一、一级缓存
mybatis的一级缓存是对SqlSession对象的缓存。
什么时候会清空一级缓存?
1.当手动调用了clearCache()方法
2.当SqlSession对象关闭了
3.当SqlSession对象执行的增、删、改、commit等
验证一级缓存的存在
@Test
public void testFirstLevelCache1() {
//查找id为1的person数据
System.out.println("-----------------1-----------------");
Person person1 = mapper.findById(1);
System.out.println(person1);
//手动调用clearCache()方法,清除缓存
// sqlSession.clearCache();
//同样查找id为1的person数据
System.out.println("-----------------2-----------------");
Person person2 = mapper.findById(1);
System.out.println(person2);
}
不清除缓存的结果:只执行了一次查询语句,说明第二次查询的数据是从缓存中取的。
清除缓存的结果:执行了两次查询语句
验证关闭SqlSession对象,会清除缓存
@Test
public void testFirstLevelCache2() {
//查找id为1的person数据
System.out.println("-----------------1-----------------");
Person person1 = mapper.findById(1);
System.out.println(person1);
//关闭SqlSession对象
sqlSession.close();
//重新打开SqlSession对象
sqlSession = factory.openSession();
mapper = sqlSession.getMapper(PersonMapper.class);
//同样查找id为1的person数据
System.out.println("-----------------2-----------------");
Person person2 = this.mapper.findById(1);
System.out.println(person2);
}
关闭SqlSession对象后的结果:执行了两次查询语句
验证SqlSession执行了修改之后,会清空缓存
@Test
public void testFirstLevelCache3() {
//查找id为1的person数据
System.out.println("-----------------1-----------------");
Person person1 = mapper.findById(1);
System.out.println(person1);
Person person = new Person();
person.setName("123");
person.setSex("女");
person.setPid(1);
//执行修改
mapper.updatePerson(person);
//同样查找id为1的person数据
System.out.println("-----------------2-----------------");
Person person2 = this.mapper.findById(1);
System.out.println(person2);
}
执行修改后的结果:执行了两次查询
二、二级缓存
mybatis的二级缓存是对SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession对象共享其缓存。
什么时候会清空二级缓存?
1.映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
2.缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
现在让同一个SqlSessionFactory对象来创建两个SqlSession对象。让SqlSession对象来创建代理对象,通过代理对象来查询同一个数据。
public void testSecondaryCache1() {
System.out.println("------------------1------------------");
SqlSession sqlSession1 = factory.openSession();
PersonMapper mapper1 = sqlSession1.getMapper(PersonMapper.class);
Person person1 = mapper1.findById(1);
System.out.println(person1);
sqlSession1.close();
System.out.println("------------------2------------------");
SqlSession sqlSession2 = factory.openSession();
PersonMapper mapper2 = sqlSession2.getMapper(PersonMapper.class);
Person person2 = mapper2.findById(1);
System.out.println(person2);
sqlSession2.close();
}
不开启二级缓存的结果:执行了两次查询语句。
配置二级缓存:
1.在Mybatis配置文件中配置(这步可以省略,因为默认值就是true):
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
2.在对应的映射文件中配置:
<cache/>
3.在某个查询语句中配置(这步也可以省略,因为默认为true):useCache=“true”
<select id="findById" resultMap="personMap" useCache="true">
select * from t_person where pid=#{pid}
</select>
开启二级缓存的结果:只查询了一次。因为是不同的SqlSession对象来执行的操作(与一级缓存无关),所以第二次数据的来自二级缓存。