面试官:说一下 MyBatis 缓存机制?

MyBatis 的缓存机制属于本地缓存,适用于单机系统,它的作用是减少数据库的查询次数,提高系统性能。

MyBaits 中包含两级本地缓存:

  1. 一级缓存:SqlSession 级别的,是 MyBatis 自带的缓存功能,默认开启,并且无法关闭,因此当有两个 SqlSession 访问相同的 SQL 时,一级缓存也不会生效,需要查询两次数据库。
  2. 二级缓存:Mapper 级别的,只要是同一个 Mapper,无论使用多少个 SqlSession 来操作,数据都是共享的,多个不同的 SqlSession 可以共用二级缓存,MyBatis 二级缓存默认是关闭的,需要使用时可手动开启,二级缓存也可以使用第三方的缓存,比如,使用 Ehcache 作为二级缓存。

一级缓存 VS 二级缓存

一级缓存和二级缓存的主要区别如下:

  1. 一级缓存是 SqlSession 级别的缓存,它的作用域是同一个 SqlSession,同一个 SqlSession 中的多次查询会共享同一个缓存。二级缓存是 Mapper 级别的缓存,它的作用域是同一个 Mapper,同一个 Mapper 中的多次查询会共享同一个缓存。
  2. 一级缓存是默认开启的,不需要手动配置。二级缓存需要手动配置,需要在 Mapper.xml 文件中添加 标签。
  3. 一级缓存的生命周期是和 SqlSession 一样长的,当 SqlSession 关闭时,一级缓存也会被清空。二级缓存的生命周期是和 MapperFactory 一样长的,当应用程序关闭时,二级缓存也会被清空。
  4. 一级缓存只能用于同一个 SqlSession 中的多次查询,不能用于跨 SqlSession 的查询。二级缓存可以用于跨 SqlSession 的查询,多个 SqlSession 可以共享同一个二级缓存。
  5. 一级缓存是线程私有的,不同的 SqlSession 之间的缓存数据不会互相干扰。二级缓存是线程共享的,多个 SqlSession 可以共享同一个二级缓存,需要考虑线程安全问题。

开启二级缓存

MyBatis 一级缓存是自带的缓存,默认开启,且无法关闭。而二级缓存默认是关闭的,因此我们只需要掌握二级缓存的开启即可。 二级缓存开启需要两步:

  1. 在 mapper xml 中添加 标签。
  2. 在需要缓存的标签上设置 useCache="true"(最新版本中,可以省略此步骤)。

完整示例实现如下:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.demo.mapper.StudentMapper">
    <cache/>
    <select id="getStudentCount" resultType="Integer" useCache="true">
        select count(*) from student
    </select>
</mapper>

编写单元测试代码:

java 复制代码
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class StudentMapperTest {
    @Autowired
    private StudentMapper studentMapper;

    @Test
    void getStudentCount() {
        int count = studentMapper.getStudentCount();
        System.out.println("查询结果:" + count);
        int count2 = studentMapper.getStudentCount();
        System.out.println("查询结果2:" + count2);
    }
}

执行以上单元测试的执行结果如下: 从以上结果可以看出,两次查询虽然使用了不同的 SqlSession,但第二次查询使用了缓存,并未查询数据库。

小结

MyBatis 的缓存机制属于本地缓存,适用于单机系统,它的作用是减少数据库的查询次数,提高系统性能。MyBatis 本地缓存有两类:一级缓存 SqlSession 级别,默认开启不能关闭,二级缓存 Mapper 级别,默认关闭,可以通过在 XML 中添加 标签开启。

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。

相关推荐
豆浆Whisky7 分钟前
Go微服务通信优化:从协议选择到性能调优全攻略|Go语言进阶(20)
后端·微服务·go
MOMO陌染8 分钟前
Python 饼图入门:3 行代码展示数据占比
后端·python
旮旯村CDN9 分钟前
深入旮旯村:我用后端架构拆解了VPN的底层逻辑
后端
花酒锄作田10 分钟前
FastAPI - Tracking ID的设计
后端
十月南城12 分钟前
SQL性能的三要素——索引、执行计划与数据分布的协同影响
后端·程序员
Lear14 分钟前
SpringBoot导出PDF终极解决方案实战!
后端
Dwzun15 分钟前
基于SpringBoot+Vue的体重管理系统【附源码+文档+部署视频+讲解)
vue.js·spring boot·后端
兔子撩架构16 分钟前
Dubbo 的同步服务调用
java·后端·spring cloud
技术不打烊18 分钟前
10 分钟搞懂 Go 并发:Goroutine vs Thread,一看就会用
后端
r***113333 分钟前
SpringBoot教程(三十二) SpringBoot集成Skywalking链路跟踪
spring boot·后端·skywalking