MyBatis 一级缓存实现详解及使用注意事项
一级缓存介绍
在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的SQL,MyBatis提供了一级缓存的方案优化这部分场景,如果是相同的SQL语句,会优先命中一级缓存,避免直接对数据库进行查询,提高性能。具体执行过程如下图所示。

每个SqlSession回话中会创建Executor执行器,每个Executor执行器中有一个Local Cache。当用户发起查询时,MyBatis根据当前执行的语句生成MappedStatement,在Local Cache进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中的话,查询数据库,结果写入Local Cache,最后返回结果给用户。
一级缓存配置
我们来看看如何使用MyBatis一级缓存。开发者只需在MyBatis的配置文件中,添加如下语句,就可以使用一级缓存。共有两个选项,SESSION或者STATEMENT,默认是SESSION级别,即在一个MyBatis会话中执行的所有语句,都会共享这一个缓存。一种是STATEMENT级别,可以理解为缓存只对当前执行的这一个Statement有效。
<setting name="localCacheScope" value="SESSION"/>
一级缓存实验
开启一级缓存,范围为会话级别,调用三次getStudentById,代码如下所示:
public void getStudentById() throws Exception {
SqlSession sqlSession = factory.openSession(true); // 自动提交事务
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
System.out.println(studentMapper.getStudentById(1)); // 查询数据库
System.out.println(studentMapper.getStudentById(1)); // 查询缓存
System.out.println(studentMapper.getStudentById(1)); // 查询缓存
}
public void addStudent() throws Exception {
SqlSession sqlSession = factory.openSession(true); // 自动提交事务
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
System.out.println(studentMapper.getStudentById(1)); // 查询数据库
System.out.println(studentMapper.addStudent(buildStudent())); // 更新数据
System.out.println(studentMapper.getStudentById(1)); // 查询数据库
sqlSession.close();
}
public void testLocalCacheScope() throws Exception {
SqlSession sqlSession1 = factory.openSession(true);
SqlSession sqlSession2 = factory.openSession(true);
StudentMapper studentMapper = sqlSession1.getMapper(StudentMapper.class);
StudentMapper studentMapper2 = sqlSession2.getMapper(StudentMapper.class);
System.out.println(studentMapper.getStudentById(1)); // 查询数据库
System.out.println(studentMapper.getStudentById(1)); // 查询缓存
System.out.println(studentMapper2.updateStudentName("小岑",1)); // 更新数据
System.out.println(studentMapper.getStudentById(1)); // 查询缓存,脏数据
System.out.println(studentMapper2.getStudentById(1)); // 查询数据库
}
一级缓存工作流程
一级缓存执行的时序图,如下图所示。

总结
- MyBatis一级缓存的生命周期和SqlSession一致。
- MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。
- MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,所以建议设定缓存级别为Statement。
MyBatis 一级缓存实现详解及使用注意事项的更多相关文章
- 《深入理解mybatis原理6》 MyBatis的一级缓存实现详解 及使用注意事项
<深入理解mybatis原理> MyBatis的一级缓存实现详解 及使用注意事项 0.写在前面 MyBatis是一个简单,小巧但功能非常强大的ORM开源框架,它的功能强大也体现在它的缓 ...
- 《深入理解mybatis原理》 MyBatis的一级缓存实现详解 及使用注意事项
MyBatis是一个简单,小巧但功能非常强大的ORM开源框架,它的功能强大也体现在它的缓存机制上.MyBatis提供了一级缓存.二级缓存 这两个缓存机制,能够很好地处理和维护缓存,以提高系统的性能.本 ...
- mybatis深入理解(五)-----MyBatis的一级缓存实现详解 及使用注意事项
0.写在前面 MyBatis是一个简单,小巧但功能非常强大的ORM开源框架,它的功能强大也体现在它的缓存机制上.MyBatis提供了一级缓存.二级缓存 这两个缓存机制,能够很好地处理和维护缓存,以提高 ...
- MyBatis 二级缓存实现详解及使用注意事项
二级缓存介绍 在上文中提到的一级缓存中,其最大的共享范围就是一个SqlSession内部,如果多个SqlSession之间需要共享缓存,则需要使用到二级缓存.开启二级缓存后,会使用CachingExe ...
- MyBatis 二级缓存全详解
目录 MyBatis 二级缓存介绍 二级缓存开启条件 探究二级缓存 二级缓存失效的条件 第一次SqlSession 未提交 更新对二级缓存影响 探究多表操作对二级缓存的影响 二级缓存源码解析 二级缓存 ...
- MyBatis一级缓存(转载)
<深入理解mybatis原理> MyBatis的一级缓存实现详解 及使用注意事项 http://demo.netfoucs.com/luanlouis/article/details/41 ...
- MyBatis 一级缓存、二级缓存全详解(一)
目录 MyBatis 一级缓存.二级缓存全详解(一) 什么是缓存 什么是MyBatis中的缓存 MyBatis 中的一级缓存 初探一级缓存 探究一级缓存是如何失效的 一级缓存原理探究 还有其他要补充的 ...
- Mybatis 一级缓存和二级缓存原理区别 (图文详解)
Java面试经常问到Mybatis一级缓存和二级缓存,今天就给大家重点详解Mybatis一级缓存和二级缓存原理与区别@mikechen Mybatis缓存 缓存就是内存中的数据,常常来自对数据库查询结 ...
- mybatis一级缓存详解
mybatis缓存分为一级缓存,二级缓存和自定义缓存.本文重点讲解一级缓存 一:前言 在介绍缓存之前,先了解下mybatis的几个核心概念: * SqlSession:代表和数据库的一次会话,向用户提 ...
随机推荐
- mysql之对象创建
1 --创建表空间 2 create tablespace tablespace_name 3 innodb and ndb: 4 add datafile 'file_name' 5 innodb ...
- synchronized底层浅析(二)
一张图了解锁升级流程:
- Sqlite 常用操作及使用EF连接Sqlite
Sqlite是一个很轻,很好用的数据库.兼容性很强,由于是一款本地文件数据库,不需要安装任何数据库服务,只需引入第三方开发包就可以.Sqlite的处理速度比MySql和PostgreSQL更快,性能很 ...
- shell脚本 批量查看mysql表条目数
一.简介 源码地址 日期:2018/4/12 介绍:查看mysql的信息,用于比对和查询条目数 效果图: 二.使用 适用:centos6+ 语言:中文 注意:适用于5.7版本,其它版本要更改变量han ...
- 新建任务(Project)
<Project2016 企业项目管理实践>张会斌 董方好 编著 新建任务,这操作简单得就跟在Excel的单元格里输入个数据一样,不过也不是一点讲究都没有. 首先得选对视图. 不是所有的视 ...
- 关于@Autowired和@Resource注解区别
区分一下@Autowired和@Resource两个注解的区别: 1.@Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配 2.@A ...
- CF955C Sad powers 题解
Content 给你 \(q\) 个询问,每次询问 \([l,r]\) 这个区间内满足 \(x=a^p(a>0,p>1)\) 的 \(x\) 的数量. 数据范围:\(1\leqslant ...
- Django的安全机制 CSRF 跨站请求访问
跨站请求伪造 一.简介 django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对于django中设置防 ...
- nginx配置文件简析
https://blog.csdn.net/wangbin_0729/article/details/82109693 #运行用户 user www-data; #启动进程,通常设置成和cpu的数量相 ...
- SpringBoot简单整合Gateway网关
引入依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>s ...