1. 程式人生 > 程式設計 >SpringBoot + Mybatis-plus實戰之Mybatis-plus的一級快取、二級快取

SpringBoot + Mybatis-plus實戰之Mybatis-plus的一級快取、二級快取

前言

現在的JAVA行業,貌似已經是SpringBoot + SpringCloud 的天下了,早期的SSH,SSM框架已經老去,與SpringBoot相結合的JPA框架雖然省去了很多的增刪改查sql,但是比較笨拙,在面對一些複雜多變的邏輯時常常力不從心,而相對應的Mybatis由於其高度的靈活性受到廣大JAVA攻城獅的歡迎。之前整合過了springboot+mybatis,前幾天看到一個面試的問一個問題,Mybatis的一級快取,二級快取。我想這個應該也是一個重點吧,所以今天決定來詳細解讀一下神祕的一二級快取。

  • 一級快取是SqlSession級別的快取。在操作資料庫時需要構造sqlSession物件,在物件中有一個數據結構(HashMap)用於儲存快取資料。不同的sqlSession之間的快取資料區域(HashMap)是互相不影響的。 一級快取是預設開啟的不用配置。
  • 二級快取是mapper級別的快取,多個SqlSession去操作同一個Mapper的sql語句,多個SqlSession可以共用二級快取,二級快取是跨SqlSession的。二級快取的開啟(實體類必須序列化),然後在配置檔案裡面配置。

MyBatis-plus 配置要點
核心要點1

mybatis-plus 在springboot 中的核心配置如下

mybatis-plus.configuration.cache-enabled=true
mybatis-plus.mapper-locations=classpath*:/mapper/*.xml
mybatis-plus.type-aliases-package=com.sch.app.mybatis.entity
logging.level.com.sch.app.mybatis.mapper= debug

所需依賴 除了基本的springboot依賴外,還有

核心要點2

<dependency>
		  <groupId>com.baomidou</groupId>
		  <artifactId>mybatis-plus-boot-starter</artifactId>
		  <version>3.3.2</version>
		</dependency>		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>
			<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>

核心要點3

mybatis 語句生成 generatorConfig.xml 用它一步生成需要的基本實體類和介面以及mapper檔案(resouses目錄下)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
  <!-- <properties resource="mybatis.properties" />
     -->
  <classPathEntry location="D:\AJava\mysql-connector-java-8.0.16.jar" />
  <context id="msqlTables" targetRuntime="MyBatis3">
    <plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin>
    <jdbcConnection connectionURL="jdbc:mysql://localhost:3306/alexshi?serverTimezone=GMT%2B8"
            driverClass="com.mysql.cj.jdbc.Driver" password="1234" userId="root" >

      <property name="nullCatalogMeansCurrent" value="true"/>
    </jdbcConnection>
    <javaTypeResolver>
      <property name="forceBigDecimals" value="false" />
    </javaTypeResolver>
    <javaModelGenerator targetPackage="com.sch.app.mybatis.entity" targetProject="SpringbootMybatis\src\main\java">
      <property name="enableSubPackages" value="true"/>
      <!-- 從資料庫返回的值被清理前後的空格 -->
      <property name="trimStrings" value="true" />
    </javaModelGenerator>
    <sqlMapGenerator targetPackage="mapper" targetProject="SpringbootMybatis\src\main\resources">
      <property name="enableSubPackages" value="true"/>
    </sqlMapGenerator>
    <javaClientGenerator type="XMLMAPPER" targetPackage="com.sch.app.mybatis.mapper" targetProject="SpringbootMybatis\src\main\java">
      <property name="enableSubPackages" value="true"/>
    </javaClientGenerator>

    <!--資料庫表-->
    <table schema="" tableName="d_dictionary"></table>
    <table schema="" tableName="d_dictionary_type"></table>
    <table schema="" tableName="c_resource"></table>
    <table schema="" tableName="c_role"></table>
    <table schema="" tableName="c_role_resource"></table>
    <table schema="" tableName="c_user_online"></table>
    <table schema="" tableName="c_user"></table>
    <table schema="" tableName="c_user_role"></table>
    <table schema="" tableName="test"></table>
  </context>
</generatorConfiguration>

在這裡插入圖片描述

這個 Run Mybatis Generator 可以在eclipse 的外掛市場下的

點選執行後生成以下內容

在這裡插入圖片描述

在這裡插入圖片描述

Mybatis-plus 一級快取的測試

首先一定要開啟日誌 方便檢視效果

logging.level.com.sch.app.mybatis.mapper= debug

com.sch.app.mybatis.mapper 也就是 mapper介面的目錄

在這裡插入圖片描述

測試程式碼1

@Autowired
private SqlSessionFactory sqlSessionFactory;

 @RequestMapping(value = "/testMybatis")
 @ResponseBody
 public void testMybatis(){
	 SqlSession sqlSession = sqlSessionFactory.openSession();
	 TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
	  for (int i = 0; i < 3; i++) {
	    Test selectByPrimaryKey = testMapper.selectByPrimaryKey(5);
	    log.info("結果:"+ selectByPrimaryKey.getUsername());
 }

在這裡插入圖片描述

結果是

在這裡插入圖片描述

可以看出,只搜尋了一次,第二三次都沒有sql列印

測試程式碼2

@RequestMapping(value = "/testMybatis")
	 @ResponseBody
	 public void testMybatis(){
		 SqlSession sqlSession = sqlSessionFactory.openSession();
		 TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
		  for (int i = 0; i < 3; i++) {
		    Test selectByPrimaryKey = testMapper.selectByPrimaryKey(5);
		    log.info("結果:"+ selectByPrimaryKey.getUsername());
		    if (i == 2) {
		    	selectByPrimaryKey.setUsername("劉惜君的妹妹");
		    	testMapper.updateByPrimaryKey(selectByPrimaryKey);
		    	Test selectByPrimaryKey2 = testMapper.selectByPrimaryKey(5);
		    	log.info("更新後的使用者名稱:"+ selectByPrimaryKey2.getUsername());
				}
	 }

列印結果:

在這裡插入圖片描述

可見,第一次我加入了更新的程式碼後再次查詢的時候,就又執行了sql語句,說明當執行插入、更新、刪除,會清空SqlSession中的一級快取。只有查詢的操作,一級快取才不會被清除。

Mybatis-plus二級快取測試

二級快取的開啟除了在配置檔案中開啟開關 還要在mapper對應開啟

在這裡插入圖片描述

測試程式碼1

@RequestMapping(value = "/testMybatis2")
		  @ResponseBody
		  public void testMybatis2(){
		  	SqlSession openSession1 = sqlSessionFactory.openSession();
		  	SqlSession openSession2 = sqlSessionFactory.openSession();
		  	TestMapper mapper1 = openSession1.getMapper(TestMapper.class);
		  	TestMapper mapper2 = openSession2.getMapper(TestMapper.class);
		  	Test selectByPrimaryKey = mapper1.selectByPrimaryKey(5);
		  	System.out.println(selectByPrimaryKey.getUsername());
		  	openSession1.close();
		  	Test selectByPrimaryKey2 = mapper2.selectByPrimaryKey(5);
		  	System.out.println(selectByPrimaryKey2.getUsername());
		  	openSession2.close();
		  }

測試結果

在這裡插入圖片描述

由測試結果可知,上述程式碼第一次查 mapper1.selectByPrimaryKey(5) 的時候執行了sql,然後關閉了第一個session 第二次 用別的sqlseeison 去查沒有呼叫sql,說明了二級換粗和sqlseesion 無關,之和mapper有關。

測試程式碼2

	@RequestMapping(value = "/testMybatis3")
		  @ResponseBody
		  public void testMybatis3(){
		  	SqlSession openSession1 = sqlSessionFactory.openSession();
		  	SqlSession openSession2 = sqlSessionFactory.openSession();
		  	SqlSession openSession3 = sqlSessionFactory.openSession();
		  	TestMapper mapper1 = openSession1.getMapper(TestMapper.class);
		  	TestMapper mapper2 = openSession2.getMapper(TestMapper.class);
		  	TestMapper mapper3 = openSession3.getMapper(TestMapper.class);
		  	Test selectByPrimaryKey = mapper1.selectByPrimaryKey(5);
		  	System.out.println(selectByPrimaryKey.getUsername());
		  	openSession1.close();
		  	selectByPrimaryKey.setUsername("劉惜君的姐姐");
		  	mapper2.updateByPrimaryKey(selectByPrimaryKey);
		  	openSession2.commit();
		  	
		  	Test selectByPrimaryKey3 = mapper3.selectByPrimaryKey(5);
		  	System.out.println(selectByPrimaryKey3.getUsername());
		  	openSession3.close();
		  }

列印結果

在這裡插入圖片描述

由此可知,做了更新mapper2.updateByPrimaryKey(selectByPrimaryKey); 之後, 二級快取才被清空。特性和一級快取很類似。

初次之外,我們可以通過userCache是來設定具體的語句是否禁用二級快取

在這裡插入圖片描述

重新執行 http://localhost:8080/testMybatis2 後的列印結果

在這裡插入圖片描述

可見 selectByPrimaryKey 這個查詢禁止二級快取後,兩次都從資料庫裡面查了。

小結

  • 一級快取是預設開始的,屬於會話級別,一個會話做多次做相同查詢會開啟,如果對查詢的資料進行更新,刪除等操作時,再次查詢會從資料庫裡查而不用一級快取。
  • 二級快取開啟最重要,請記住三點,1.配置檔案開啟mybatis-plus.configuration.cache-enabled=true,2.對應mapper檔案開啟 3.對應實體類實現Serializable 介面。如果要對某一個sql語句禁用二級快取,則需要在具體的xml 的sql語句定義處加上 useCache=“false” 。另外記住它和會話無關,和 xml 的 namespace 即具體的mapper 有關。
  • 在mapper的同一個namespace中,如果有其它insert、update、delete操作資料後需要重新整理快取,如果不執行重新整理快取會出現髒讀。
  • 設定statement配置中的flushCache=“true” 屬性,可以實現二級快取的重新整理,false則可能出現髒讀。openSession.clearCache() 可以實現對一級快取的重新整理。

到此這篇關於SpringBoot + Mybatis-plus實戰之Mybatis-plus的一級快取、二級快取的文章就介紹到這了,更多相關Mybatis-plus一級快取、二級快取內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!