面試官:說一下 MyBatis 快取機制?

2023-09-12 18:01:53

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 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>

編寫單元測試程式碼:

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、設計模式、訊息佇列等模組。