【每天5分钟,了解一个知识点】
今天我们来深入了解一下 MyBatis 中的一级与二级缓存。在实际开发中,合理运用缓存可以大大提高数据访问的效率,减少数据库的压力。那么,MyBatis 的一级和二级缓存到底是什么呢?它们又有哪些作用范围、原理以及注意事项呢?让我们一起来一探究竟吧!
一、MyBatis 缓存简介
在使用 MyBatis 进行数据库操作时,缓存是一个非常重要的特性。缓存的目的是为了减少对数据库的访问次数,提高数据查询的性能。MyBatis 提供了一级缓存和二级缓存两种缓存机制。
二、一级缓存
作用范围
一级缓存是 SqlSession 级别的缓存,也称为本地缓存。
同一个 SqlSession 中执行相同的 SQL 查询,第一次查询会从数据库中获取数据,并将数据放入缓存中。后续再次执行相同的 SQL 查询时,会直接从缓存中获取数据,而不会再次访问数据库。
原理
MyBatis 在执行 SQL 查询时,会将查询结果放入一个 Map 中,以 SQL 语句和参数作为键,查询结果作为值。
当再次执行相同的 SQL 查询时,MyBatis 会先根据 SQL 语句和参数在缓存中查找是否有对应的结果。如果有,则直接返回缓存中的结果;如果没有,则从数据库中查询,并将结果放入缓存中。
一级缓存的 key一级缓存的 key 由以下几个因素决定:
SQL 语句:完全相同的 SQL 语句会命中同一级缓存。
参数:如果 SQL 语句的参数不同,也会被视为不同的查询,不会命中缓存。
结果集范围(如分页参数):即使 SQL 语句和参数相同,但如果分页参数不同,也不会命中缓存。
例如,以下两个查询虽然 SQL 语句相同,但由于参数不同,不会命中一级缓存:
// 查询 id 为 1 的用户User user1 = sqlSession.selectOne(\"select * from user where id = 1\");// 查询 id 为 2 的用户User user2 = sqlSession.selectOne(\"select * from user where id = 2\");
4. 注意事项
一级缓存是默认开启的,不需要进行额外的配置。
一级缓存只在同一个 SqlSession 中有效,不同的 SqlSession 之间的缓存是相互独立的。
如果在同一个 SqlSession 中执行了任何一次增删改操作,MyBatis 会清空该 SqlSession 中的一级缓存,以确保缓存中的数据与数据库中的数据一致。
三、二级缓存
作用范围
二级缓存是 Mapper 级别的缓存,也称为全局缓存。
多个 SqlSession 可以共享同一个 Mapper 的二级缓存。不同的 SqlSession 执行相同的 Mapper 查询时,如果二级缓存中有对应的结果,则可以直接从缓存中获取数据,而不会再次访问数据库。
原理
MyBatis 的二级缓存是基于装饰器模式实现的。当开启二级缓存后,MyBatis 会在执行 SQL 查询时,先从二级缓存中查找是否有对应的结果。如果有,则直接返回缓存中的结果;如果没有,则从数据库中查询,并将结果放入二级缓存中。
二级缓存的存储介质可以是内存或者硬盘,具体取决于配置。默认情况下,二级缓存是存储在内存中的。
二级缓存的 key二级缓存的 key 主要由以下因素决定:
SQL 语句:完全相同的 SQL 语句会命中同一级缓存。
参数:如果 SQL 语句的参数不同,也会被视为不同的查询,不会命中缓存。
结果集范围(如分页参数):即使 SQL 语句和参数相同,但如果分页参数不同,也不会命中缓存。
例如,在两个不同的 Mapper 中执行相同的 SQL 语句,不会命中二级缓存:
// Mapper1
User user1 = mapper1.selectOne(\"select * from user where id = 1\");
// Mapper2
User user2 = mapper2.selectOne(\"select * from user where id = 1\");
二级缓存需要在 Mapper.xml 文件中进行配置才能开启。可以通过设置
<cache/>
标签来开启二级缓存。二级缓存的作用范围是 Mapper 级别,不同的 Mapper 之间的缓存是相互独立的。
如果在 Mapper 中执行了任何一次增删改操作,MyBatis 会清空该 Mapper 的二级缓存,以确保缓存中的数据与数据库中的数据一致。
二级缓存中的数据可能会因为数据库中的数据变化而变得过时。因此,在使用二级缓存时,需要根据实际情况设置合理的缓存过期时间,以确保缓存中的数据始终是最新的。
4. 注意事项

四、常见面试题
MyBatis 的一级缓存和二级缓存有什么区别?
作用范围不同:一级缓存是 SqlSession 级别的,二级缓存是 Mapper 级别的。
多个 SqlSession 能否共享:一级缓存不能被多个 SqlSession 共享,二级缓存可以被多个 SqlSession 共享。
配置方式不同:一级缓存默认开启,无需配置;二级缓存需要在 Mapper.xml 文件中进行配置才能开启。
如何开启 MyBatis 的二级缓存?
在 Mapper.xml 文件中添加
<cache/>
标签即可开启二级缓存。在使用 MyBatis 的二级缓存时,需要注意哪些问题?
需要在 Mapper.xml 文件中进行配置才能开启。
不同的 Mapper 之间的缓存是相互独立的。
如果在 Mapper 中执行了任何一次增删改操作,MyBatis 会清空该 Mapper 的二级缓存。
二级缓存中的数据可能会因为数据库中的数据变化而变得过时,需要设置合理的缓存过期时间




