Data Access 之 MyBatis(五)- MyBatis Cache(上)

简介: Data Access 之 MyBatis(五)- MyBatis Cache

MyBatis缓存

MyBatis包含一个非常强大的查询缓存特性,可以非常方便的配置和定义。缓存可以极大的提高查询效率

MyBatis系统中默认定义了两个级别的缓存,一级缓存和二级缓存;默认情况下,只有一级缓存开启,二级缓存的开启需要手动配置

  • 一级缓存:线程级别的缓存,本地缓存、Sql Session级别的缓存
  • 二级缓存:全局范围的缓存,除过当前线程,sqlSession能用外其他也可以使用 MyBatis实际是将缓存放在Map中

工程搭建

复制mybatis-dynamic-sql项目,并重命名为mybatis-cache,注意要修改pom.xml中artifactId为mybatis-cache,重新打开项目即可

一级缓存

  • 一级缓存(local cache)即本地缓存,作用域默认为sqlSession,当session flush或者close后,该session中所有的cache将会被清空
  • 本地缓存不能被关闭,但是可以调用clearCache()方法清空,或者改变缓存的作用域

一级缓存生效

同一会话期间只要查询过的数据都会保存在当前的sqlSession的一个Map中,Map的key为hashCode + 查询的SQLId + 编写的SQL语句 + SQL的参数

新增测试方法testCacheWithSameSession,先后获取同一个Teacher,在同一session下

@Test
public void testCacheWithSameSession(){
    TeacherMapper teacherMapper = openSession.getMapper(TeacherMapper.class);
    Teacher teacher = teacherMapper.getTeacherById(1);
    System.out.println(teacher);
    System.out.println("---------------------------------------------------");
    Teacher teacher1 = teacherMapper.getTeacherById(1);
    System.out.println(teacher1);
}
复制代码

执行测试

d7bc8b1568294aeba33a5e65a81a46fd_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

从控制台输出内容可以看出,只执行了一次查询SQL。

一级缓存失效的几种情况

  • 不同的sqlSession对应不同的一级缓存
  • 同一个sqlSession但是查询条件不同
  • 同一个sqlSession两次查询期间执行了一次更新操作
  • 同一个sqlSession两次查询期间手动清空了缓存

同一个sqlSession但是查询条件不同

不同的sqlSession使用不同的一级缓存,只有在同一个sqlSession期间查询到的数据会保存在这个sqlSession中,下次查询才可以从缓存中拿到

新增测试方法testCacheWithDiffSession

@Test
public void testCacheWithDiffSession(){
    SqlSession sqlSession1 = sqlSessionFactory.openSession();
    SqlSession sqlSession2 = sqlSessionFactory.openSession();
    TeacherMapper teacherMapper1 = sqlSession1.getMapper(TeacherMapper.class);
    TeacherMapper teacherMapper2 = sqlSession2.getMapper(TeacherMapper.class);
    teacherMapper1.getTeacherById(1);
    teacherMapper2.getTeacherById(1);
    sqlSession1.close();
    sqlSession2.close();
}
复制代码

执行测试

f2160220f36148f1bac680c319db74b8_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

控制台输出两条SQL语句

同一个sqlSession但是查询条件不同

同一个方法,不同的参数,也可能之前没有执行过没有缓存数据,还是会发新的SQL

增加测试方法testCacheWithSameSessionByDiffCondition

@Test
public void testCacheWithSameSessionByDiffCondition(){
    SqlSession sqlSession1 = sqlSessionFactory.openSession();
    TeacherMapper teacherMapper1 = sqlSession1.getMapper(TeacherMapper.class);
    teacherMapper1.getTeacherById(1);
    teacherMapper1.getTeacherById(2);
    sqlSession1.close();
}
复制代码

执行测试

cadba3846c2545fc811a77fe249cedc1_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

控制台输出两条SQL语句

同一个sqlSession两次查询期间执行了一次更新操作

更新操作包括删除和新增,即使操作的不是要查询的数据也会把缓存清空

新增测试方法testCacheWithSameSessionAndConditionAfterUpdate()

@Test
public void testCacheWithSameSessionAndConditionAfterUpdate(){
    SqlSession sqlSession1 = sqlSessionFactory.openSession();
    TeacherMapper teacherMapper1 = sqlSession1.getMapper(TeacherMapper.class);
    teacherMapper1.getTeacherById(1);
    Teacher teacher3 = new Teacher();
    teacher3.setId(3);
    teacher3.setClassName("三年三十班");
    teacherMapper1.updateTeacher(teacher3);
    teacherMapper1.getTeacherById(1);
    sqlSession1.close();
}
复制代码

执行测试

eac3193681b64fea86a097860b81d457_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

控制台输出了两条SQL语句

同一个sqlSession两次查询期间手动清空缓存

增加测试方法testCacheWithSameSessionAndConditionAfterCleanCacheManually()

@Test
public void testCacheWithSameSessionAndConditionAfterCleanCacheManually(){
    SqlSession sqlSession1 = sqlSessionFactory.openSession();
    TeacherMapper teacherMapper1 = sqlSession1.getMapper(TeacherMapper.class);
    teacherMapper1.getTeacherById(1);
    // 手动清空当前SqlSession的一级缓存
    sqlSession1.clearCache();
    teacherMapper1.getTeacherById(1);
    sqlSession1.close();
}
复制代码

执行测试

eac3193681b64fea86a097860b81d457_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

控制它输出两条SQL语句

每次查询,MyBatis都会先看看缓存中有没有数据,如果没有才会发送新的SQL,每个SqlSession都有自己的一级缓存


相关文章
|
5月前
|
druid Java 数据库连接
SpringBoot原理分析 | Spring Data整合:JDBC、Druid、Mybatis
SpringBoot原理分析 | Spring Data整合:JDBC、Druid、Mybatis
70 0
|
5月前
|
存储 设计模式 Java
Mybatis源码细节探究:二级缓存Cache对象是在什么时候创建的?
Mybatis源码细节探究:二级缓存Cache对象是在什么时候创建的?
|
5月前
|
SQL 缓存 Java
Mybatis源码细节探究:MappedStatement和Cache对象对照关系研究
Mybatis源码细节探究:MappedStatement和Cache对象对照关系研究
|
5月前
|
XML 缓存 Java
你尝试过在mybatis某个mapper上同时配置<cache/>和<cache-ref/>吗?
你尝试过在mybatis某个mapper上同时配置<cache/>和<cache-ref/>吗?
46 0
|
SQL 缓存 Java
Data Access 之 MyBatis Plus(四)- MyBatis Plus Plugin
Data Access 之 MyBatis Plus(四)- MyBatis Plus Plugin
Data Access 之 MyBatis Plus(四)- MyBatis Plus Plugin
|
Java 数据库连接 PHP
Data Access 之 MyBatis Plus(六)- ActiveRecord
Data Access 之 MyBatis Plus(六)- ActiveRecord
Data Access 之 MyBatis Plus(六)- ActiveRecord
|
SQL Java 数据库连接
Data Access 之 MyBatis Plus(五)- 自定义 BaseMapper
Data Access 之 MyBatis Plus(五)- 自定义 BaseMapper
Data Access 之 MyBatis Plus(五)- 自定义 BaseMapper
|
SQL Java 数据库连接
Data Access 之 MyBatis Plus(三)- MPG代码生成器(Part B)
Data Access 之 MyBatis Plus(三)- MPG代码生成器(Part B)
Data Access 之 MyBatis Plus(三)- MPG代码生成器(Part B)
|
XML SQL Java
Spring 全家桶之 Spring Boot 2.6.4(四)- Data Access(Part D MyBatis Plus)
Spring 全家桶之 Spring Boot 2.6.4(四)- Data Access(Part D MyBatis Plus)
Spring 全家桶之 Spring Boot 2.6.4(四)- Data Access(Part D MyBatis Plus)
|
2月前
|
SQL Java 数据库连接
挺详细的spring+springmvc+mybatis配置整合|含源代码
挺详细的spring+springmvc+mybatis配置整合|含源代码
76 1