MyBatis 的緩存機制屬于本地緩存,適用于單機系統,它的作用是減少數據庫的查詢次數,提高系統性能。
MyBAIts 中包含兩級本地緩存:
-
一級緩存:SqlSession 級別的,是 MyBatis 自帶的緩存功能,默認開啟,并且無法關閉,因此當有兩個 SqlSession 訪問相同的 SQL 時,一級緩存也不會生效,需要查詢兩次數據庫。 -
二級緩存:MApper 級別的,只要是同一個 Mapper,無論使用多少個 SqlSession 來操作,數據都是共享的,多個不同的 SqlSession 可以共用二級緩存,MyBatis 二級緩存默認是關閉的,需要使用時可手動開啟,二級緩存也可以使用第三方的緩存,比如,使用 Ehcache 作為二級緩存。
一級緩存 VS 二級緩存
一級緩存和二級緩存的主要區別如下:
-
一級緩存是 SqlSession 級別的緩存,它的作用域是同一個 SqlSession,同一個 SqlSession 中的多次查詢會共享同一個緩存。二級緩存是 Mapper 級別的緩存,它的作用域是同一個 Mapper,同一個 Mapper 中的多次查詢會共享同一個緩存。 -
一級緩存是默認開啟的,不需要手動配置。二級緩存需要手動配置,需要在 Mapper.xml 文件中添加標簽。 -
一級緩存的生命周期是和 SqlSession 一樣長的,當 SqlSession 關閉時,一級緩存也會被清空。二級緩存的生命周期是和 MapperFactory 一樣長的,當應用程序關閉時,二級緩存也會被清空。 -
一級緩存只能用于同一個 SqlSession 中的多次查詢,不能用于跨 SqlSession 的查詢。二級緩存可以用于跨 SqlSession 的查詢,多個 SqlSession 可以共享同一個二級緩存。 -
一級緩存是線程私有的,不同的 SqlSession 之間的緩存數據不會互相干擾。二級緩存是線程共享的,多個 SqlSession 可以共享同一個二級緩存,需要考慮線程安全問題。
開啟二級緩存
MyBatis 一級緩存是自帶的緩存,默認開啟,且無法關閉。而二級緩存默認是關閉的,因此我們只需要掌握二級緩存的開啟即可。二級緩存開啟需要兩步:
-
在 mapper xml 中添加標簽。 -
在需要緩存的標簽上設置 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 中添加標簽開啟。