最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java Mybatis一級緩存和二級緩存

 更新時間:2023年04月07日 09:10:30   作者:會洗碗的CV工程師  
緩存是內存當中一塊存儲數據的區(qū)域,目的是提高查詢效率,降低服務器和數據庫的壓力,這篇文章主要介紹了Mybatis一級緩存和二級緩存,感興趣的同學可以參考閱讀本文

一、什么是緩存 

        緩存是內存當中一塊存儲數據的區(qū)域,目的是提高查詢效率。MyBatis會將查詢結果存儲在緩存當中,當下次執(zhí)行相同的SQL時不訪問數據庫,而是直接從緩存中獲取結果,從而減少服務器的壓力。

什么是緩存?

存在于內存中的一塊數據。

緩存有什么作用?

減少程序和數據庫的交互,提高查詢效率,降低服務器和數據庫的壓力。

什么樣的數據使用緩存?

經常查詢但不常改變的,改變后對結果影響不大的數據。

MyBatis緩存分為哪幾類?

 一級緩存和二級緩存

如何判斷兩次Sql是相同的?

查詢的Sql語句相同 傳遞的參數值相同 對結果集的要求相同 預編譯的模板Id相同

二、Mabtis一級緩存

MyBatis一級緩存也叫本地緩存。SqlSession對象中包含一個Executor對象,Executor對象中包含一個PerpetualCache對象,在該對象存放一級緩存數據。

由于一級緩存是在SqlSession對象中,所以只有使用同一個SqlSession對象操作數據庫時才能共享一級緩存。

MyBatis的一級緩存是默認開啟的,不需要任何的配置。

如下圖所示:

(1)測試一級緩存

其實測試方法很簡單,就是通過使用相同和不同的SqlSession對象進行SQL查詢,返回的對象的哈希值是否一樣就可以知道了,如果返回的哈希值一樣說明沒有進行SQL查詢,而是直接從緩存拿到對象來返回

下面是使用相同的Session對象來執(zhí)行查詢,如果觀察user1和user2的哈希值一樣則說明確實開啟了一級緩存,并沒有進行查詢,而是直接從緩存中拿數據。 

import com.mybatisstudy.mapper.UserMapper;
import com.mybatisstudy.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
 
import java.io.InputStream;
 
public class TestUserMapper3 {
    // 測試使用同一個SqlSession查詢
    @Test
    public void testCache1() throws Exception{
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);
        SqlSession session = factory.openSession();
 
        // 使用同一個SqlSession查詢
        UserMapper mapper1 = session.getMapper(UserMapper.class);
        UserMapper mapper2 = session.getMapper(UserMapper.class);
 
        User user1 = mapper1.findById(1);
        System.out.println(user1.hashCode());
        System.out.println("------------------------------------------");
        User user2 = mapper2.findById(1);
        System.out.println(user2.hashCode());
 
        session.close();
    }
}

執(zhí)行結果 

        OK,確實返回的哈希值都是一樣的,并且我們可以通過控制臺輸出顯示它并沒有進行查詢而是直接從緩存中拿到對象并返回,所以這就是一級緩存 ,提高了查詢效率。

        下面使用不同的SqlSession來進行測試一下,返回的哈希值是否一致 

// 測試使用不同SqlSession查詢
    @Test
    public void testCache2() throws Exception{
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);
        SqlSession session1 = factory.openSession();
        SqlSession session2 = factory.openSession();
 
        // 測試使用不同SqlSession查詢
        UserMapper mapper1 = session1.getMapper(UserMapper.class);
        UserMapper mapper2 = session2.getMapper(UserMapper.class);
 
        User user1 = mapper1.findById(1);
        System.out.println(user1.hashCode());
        System.out.println("---------------------------------");
        User user2 = mapper2.findById(1);
        System.out.println(user2.hashCode());
 
        session1.close();
        session2.close();
    }

運行結果

        OK,可以看到,返回的哈希值不一樣,并且從控制臺輸出顯示也可以看到這里的確也進行了一次查詢,因此可以證實,共享一級緩存確實是基于SqlSession對象的 

(2)清空一級緩存

        但是吧,如果緩存過多的話,也是會影響我們的查詢效率的,所以這時候就需要清空緩存了,就像我們時不時要清理一下手機緩存否則就會很卡,是同樣的道理,那怎么清空一級緩存呢?

進行以下操作可以清空MyBatis一級緩存:

  • SqlSession 調用 close() :操作后SqlSession對象不可用,該對象的緩存數據也不可用。
  • SqlSession 調用 clearCache() / commit() :操作會清空一級緩存數據。
  • SqlSession 調用增刪改方法:操作會清空一級緩存數據,因為增刪改后數據庫發(fā)生改變,緩存數據將不準確
// 清空Mybatis一級緩存
    @Test
    public void testCache3() throws Exception{
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);
        SqlSession session = factory.openSession();
 
        UserMapper mapper1 = session.getMapper(UserMapper.class);
        UserMapper mapper2 = session.getMapper(UserMapper.class);
 
        User user1 = mapper1.findById(1);
        System.out.println(user1.hashCode());
 
        // 清空Mybatis一級緩存
        session.clearCache();
 
        System.out.println("-------------------------------");
        User user2 = mapper2.findById(1);
        System.out.println(user2.hashCode());
 
        session.close();
    }

執(zhí)行效果

        OK,返回的哈希值也確實不一樣, 但是我們有沒有觀察到這和上面使用不同的SqlSession對象來執(zhí)行查詢的時候,控制臺輸入顯示有點不一樣,那就是這里不用再建立JDBC連接,也有效了提高查詢效率,所以我們偶爾還是要清空一下緩存才行

三、Mybatis二級緩存

MyBatis二級緩存也叫全局緩存。數據存放在SqlSessionFactory中,只要是同一個工廠對象創(chuàng)建的SqlSession,在進行查詢時都能共享數據。一般在項目中只有一個SqlSessionFactory對象,所以二級緩存的數據是全項目共享的。
MyBatis一級緩存存放的是對象,二級緩存存放的是對象的數據。所以要求二級緩存存放的POJO必須是可序列化的,也就是要實現Serializable接口。
MyBatis二級緩存默認不開啟,手動開啟后數據先存放在一級緩存中,只有一級緩存數據清空后,數據才會存到二級緩存中。           
SqlSession 調用 clearCache() 無法將數據存到二級緩存中。

(1)開啟二級緩存

1. POJO類實現Serializable接口

import java.io.Serializable;
 
public class User implements Serializable {
    private int id;
    private String username;
    private String sex;
    private String address;
}

2. 在Mybatis配置文件添加如下設置

<!-- 二級緩存打開 -->
<settings>   
 <setting name="cacheEnabled" value="true"/>
</settings>

這里有個額外知識,就是Mybatis配置文件的標簽還得按照順序來放的,否則就會以下編譯錯誤;

The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,

objectWrapperFactory?,reflectorFactory?,plugins?,environments?,

databaseIdProvider?,mappers?)". 

  同時也說明了放置順序就得按照match里面的順序來放

3. 添加 <cache /> 標簽

 如果查詢到的集合中對象過多,二級緩存只能緩存1024個對象引用??梢酝ㄟ^

<cache /> 標簽的size屬性修改該數量。

比如:<cache size="2048"/>

(2)測試二級緩存

        那怎么測試呢,從上面我們可以知道二級緩存存放的是對象的數據,并且是基于SqlSessionFactory的,因此我們可以用SqlSessionFactory獲取兩個SqlSession對象,然后讓他們分別獲取各自的mapper,然后進行查詢,返回到同一個實例化的USer對象中,如果返回的數據是一致的,但是對象的哈希值是不一樣的話,則說明二級緩存里存放的確實對象的數據而不是對象。

// 測試二級緩存
@Test
public void testCache4() throws Exception {
    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(is);
    SqlSession session = factory.openSession();

    UserMapper mapper1 = session.getMapper(UserMapper.class);
    UserMapper mapper2 = session.getMapper(UserMapper.class);

    User user1 = mapper1.findById(1);
    System.out.println(user1);
    System.out.println(user1.hashCode());

    // 讓一級緩存失效
    session.commit();
    System.out.println("----------------------------");

    user1 = mapper2.findById(1);
    System.out.println(user1);
    System.out.println(user1.hashCode());
}

運行結果 

        OK,從運行結果上我們可以知道結果集返回到同一個對象中,而他們的哈希值反而不一樣,說明執(zhí)行第二次查詢的時候新建了一個對象并且該對象指向那個對象并且將SqlSessionFactory中的數據賦值到新建的那個對象。其實從控制臺打印的日志我們也可以得出,并沒有執(zhí)行查詢方法,因為沒有打印SQL語句,而且緩存也是從0.0改成了0.5,因此我們可以斷定二級緩存存放的是數據而不是對象。

到此這篇關于Java Mybatis一級緩存和二級緩存的文章就介紹到這了,更多相關Mybatis一級緩存和二級緩存內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java設計模式-單例模式實現方法詳解

    java設計模式-單例模式實現方法詳解

    單例模式,屬于創(chuàng)建類型的一種常用的軟件設計模式。通過單例模式的方法創(chuàng)建的類在當前進程中只有一個實例(根據需要,也有可能一個線程中屬于單例
    2021-07-07
  • springboot將lib和jar分離的操作方法

    springboot將lib和jar分離的操作方法

    本文介紹了如何通過優(yōu)化pom.xml配置來減小Spring Boot項目的jar包大小,主要通過使用spring-boot-maven-plugin和maven-dependency-plugin插件,將依賴庫打包到jar中,并通過指定外部lib路徑的方式運行jar,從而減小jar包體積,感興趣的朋友一起看看吧
    2025-02-02
  • Spring Boot整合Spring Data Jpa代碼實例

    Spring Boot整合Spring Data Jpa代碼實例

    這篇文章主要介紹了Spring Boot整合Spring Data Jpa代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • 基于Redisson實現注解式分布式鎖的示例代碼

    基于Redisson實現注解式分布式鎖的示例代碼

    這篇文章主要為大家詳細介紹了如何基于Redisson實現注解式分布式鎖,文中的示例代碼講解詳細,具有一定的參考價值,需要的可以了解一下
    2023-07-07
  • Java 對HashMap進行排序的三種常見方法

    Java 對HashMap進行排序的三種常見方法

    這篇文章主要介紹了Java 對HashMap進行排序的三種常見方法,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-10-10
  • SpringBoot中實現訂單30分鐘自動取消的三種方案分享

    SpringBoot中實現訂單30分鐘自動取消的三種方案分享

    在電商和其他涉及到在線支付的應用中,通常需要實現一個功能:如果用戶在生成訂單后的一定時間內未完成支付,系統(tǒng)將自動取消該訂單,本文將詳細介紹基于Spring Boot框架實現訂單30分鐘內未支付自動取消的幾種方案,并提供實例代碼,需要的朋友可以參考下
    2023-10-10
  • Spring?Boot項目中使用OpenAI-Java的示例詳解

    Spring?Boot項目中使用OpenAI-Java的示例詳解

    Spring?Boot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發(fā)過程,這篇文章主要介紹了Spring?Boot項目中使用OpenAI-Java的示例詳解,需要的朋友可以參考下
    2023-04-04
  • 詳解Spring注解 @Configuration

    詳解Spring注解 @Configuration

    @Configuration 是 Spring 中的一個注解,它用于標記一個類為配置類,通過配置類可以定義和組裝 Spring Bean,并且支持高度靈活的配置方式。本問詳細介紹了Spring注解 @Configuration,感興趣的小伙伴可以參考一下
    2023-04-04
  • SpringMVC響應視圖和結果視圖詳解

    SpringMVC響應視圖和結果視圖詳解

    這篇文章主要介紹了SpringMVC響應視圖和結果視圖,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 一文淺析Java中的值傳遞

    一文淺析Java中的值傳遞

    今天在解決一個問題時,程序總是不能輸出正確值,分析邏輯思路沒問題后,發(fā)現原來是由于函數傳遞導致了這個情況,下面我們就來看看Java中的值傳遞到底是什么情況吧
    2023-08-08

最新評論

老河口市| 敦煌市| 吐鲁番市| 晋城| 梅州市| 合肥市| 河池市| 咸宁市| 金华市| 西平县| 乌什县| 本溪| 车致| 荥经县| 津市市| 渝中区| 大渡口区| 阜康市| 旺苍县| 加查县| 精河县| 申扎县| 财经| 合山市| 平邑县| 黑水县| 博客| 合山市| 朔州市| 霍城县| 延安市| 绥化市| 班玛县| 刚察县| 绥德县| 仁化县| 蓝山县| 湘潭县| 武安市| 霍林郭勒市| 镇坪县|