Java 面试常常问到 Mybatis 一级缓存和二级缓存,明天就给大家重点详解 Mybatis 一级缓存和二级缓存原理与区别 @mikechen
Mybatis 缓存
缓存就是内存中的数据,经常来自对数据库查问后果的保留,应用缓存能够防止频繁与数据库进行交互,从而进步查问响应速度。
MyBatis 提供了对缓存的反对,分为一级缓存和二级缓存,如下图所示:
咱们先大抵理解下 MyBatis 一级缓存与 MyBatis 二级缓存:
一级缓存:SqlSession 级别的缓存,缓存的数据只在 SqlSession 内无效。
二级缓存:mapper 级别的缓存,同一个 namespace 专用这一个缓存,所以对 SqlSession 是共享的,二级缓存须要咱们手动开启。
上面咱们再别离详解两者的原理与区别。
\
Mybatis 一级缓存
1. 为什么须要 Mybatis 一级缓存
当咱们应用 Mybatis 进行数据库的操作时候,会创立一个 SqlSession 来进行一次数据库的会话,会话完结则敞开 SqlSession 对象。
如果咱们很有可能屡次查问完全相同的 sql 语句,每一次查问都查问一次数据库,那查询数据库代价是比拟大的,这会导致系统的资源节约。
为了解决这个问题,Mybatis 对每一次会话都增加了缓存操作,不必雷同的 SQL 每次都须要查询数据库,这就是 Mybatis 一级缓存的作用。
\
2.Mybatis 一级缓存的实现
咱们晓得对 SqlSession 的操作,mybatis 外部都是通过 Executor 来执行的,Executor 的生命周期和 SqlSession 是统一的。
Mybatis 在 Executor 中创立了本地缓存 (一级缓存),如下图所示:
大抵的流程如下:
第一次查问用户 id 信息,先去缓存中查问是否有,如果没有,从数据库中查问用户信息,失去用户信息后在将用户信息贮存到一级缓存中。
如果 sqlSession 去执行 commit 操作(插入、更新、删除),清空 sqlSession 中的一级缓存,保障缓存中始终保留的是最新的信息,防止脏读。
第二次查问用户 id 信息,先去缓存中查问,如缓存中有,间接从缓存中获取。
留神:两次查问须在同一个 sqlsession 中实现,否则将不会走 mybatis 的一级缓存。
在 mybatis 与 spring 进行整合开发时,事务管制在 service 中进行,反复调用两次 servcie 将不会走一级缓存,因为在第二次调用时 session 办法完结,SqlSession 就敞开了。
\
3.Mybatis 一级缓存配置
mybatis 一级缓存的范畴有 SESSION 和 STATEMENT 两种,默认是 SESSION。
如果不想应用一级缓存,能够把一级缓存的范畴指定为 STATEMENT,这样每次执行完一个 Mapper 中的语句后都会将一级缓存革除。
如果须要更改一级缓存的范畴,能够在 Mybatis 的配置文件中,在下通过 localCacheScope 指定。
<setting name="localCacheScope" value="STATEMENT"/>
\
Mybatis 二级缓存
1. 为什么须要 Mybatis 二级缓存?
MyBatis 一级缓存最大的共享范畴就是一个 SqlSession 外部,那么如果多个 SqlSession 须要共享缓存,则须要开启二级缓存。
\
2.Mybatis 二级缓存的实现
开启二级缓存后,会应用 CachingExecutor 装璜 Executor,进入一级缓存的查问流程前,先在 CachingExecutor 进行二级缓存的查问,具体的工作流程如下所示。
二级缓存开启后,同一个 namespace 下的所有操作语句,都影响着同一个 Cache,即二级缓存被多个 SqlSession 共享,是一个全局的变量。
当开启缓存后,数据的查问执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。
MyBatis 是默认敞开二级缓存的,因为对于增删改操作频繁的话,那么二级缓存形同虚设,每次都会被清空缓存。
\
Mybatis 一级缓存与二级缓存的区别
1)一级缓存 Mybatis 的一级缓存是指 SQLSession,一级缓存的作用域是 SQlSession, Myabits 默认开启一级缓存。
在同一个 SqlSession 中,执行雷同的 SQL 查问时;第一次会去查询数据库,并写在缓存中,第二次会间接从缓存中取。当执行 SQL 时候两次查问两头产生了增删改的操作,则 SQLSession 的缓存会被清空。
每次查问会先去缓存中找,如果找不到,再去数据库查问,而后把后果写到缓存中。Mybatis 的外部缓存应用一个 HashMap,key 为 hashcode+statementId+sql 语句。Value 为查问进去的后果集映射成的 java 对象。SqlSession 执行 insert、update、delete 等操作 commit 后会清空该 SQLSession 缓存。
2)Mybatis 二级缓存是默认不开启的,作用于一个 Application,是 Mapper 级别的,多个 SqlSession 应用同一个 Mapper 的 sql 可能应用二级缓存。
以上
作者简介
陈睿 |mikechen,10 年 + 大厂架构教训,《BAT 架构技术 500 期》系列文章作者,分享十余年架构教训以及面试心得!
浏览 mikechen 的互联网架构更多技术文章合集
Java 并发 |JVM|MySQL|Spring|Redis| 分布式 | 高并发 | 架构师
关注「mikechen 的互联网架构」公众号,回复 【架构】 支付我原创的《300 期 + BAT 架构技术系列与 1000 + 大厂面试题答案》