MyBaties一級緩存

1、一級緩存簡介

在系統代碼的運行中,咱們可能會在一個數據庫會話中,執行屢次查詢條件徹底相同的Sql,鑑於平常應用的大部分場景都是讀多寫少,這重複的查詢會帶來必定的網絡開銷,同時select查詢的量比較大的話,對數據庫的性能是有比較大的影響的。Mybatis提供了一級緩存的方案來優化在數據庫會話間重複查詢的問題。實現的方式是每個SqlSession中都持有了本身的緩存:spring

一種是SESSION級別,即在一個Mybatis會話中執行的全部語句,都會共享這一個緩存
一種是STATEMENT級別,能夠理解爲緩存只對當前執行的這一個statement有效sql

用一張圖來解釋一級緩存,以下圖:數據庫

 

每個SqlSession中持有了本身的Executor,每個Executor中有一個Local Cache。當用戶發起查詢時,Mybatis會根據當前執行的MappedStatement生成一個key,去Local Cache中查詢,若是緩存命中的話,返回。若是緩存沒有命中的話,則寫入Local Cache,最後返回結果給用戶。
 緩存

2、一級緩存配置

只須要在Mybatis的配置文件中,添加以下語句,就可使用一級緩存。共有兩個選項,SESSION或者STATEMENT,默認是SESSION級別
<setting name="localCacheScope" value="SESSION"/>網絡

注意:spring結合mybatis時一級緩存失效問題
一、在未開啓事物的狀況之下,每次查詢,spring都會關閉舊的sqlSession而建立新的sqlSession,所以此時的一級緩存是沒有啓做用的mybatis

二、在開啓事物的狀況之下,spring使用threadLocal獲取當前資源綁定同一個sqlSession,所以此時一級緩存是有效的app

3、一級緩存測試

    測試1、
    開啓一級緩存,範圍爲會話級別,調用兩次selectByPrimaryKey分佈式

@Transactional
    public void test4() {
        
        User user=userMapper.selectByPrimaryKey(1);
        System.out.println(user);
        User user2=userMapper.selectByPrimaryKey(1);
        System.out.println(user2);
       
    }

咱們能夠看到,只有第一次真正查詢了數據庫,後續的查詢使用了一級緩存性能

 

測試2、
在此次的試驗中,咱們增長了對數據庫的修改操做,驗證在一次數據庫會話中,對數據庫發生了修改操做,一級緩存是否會失效測試

@Transactional
    public void test4() {
        User user=userMapper.selectByPrimaryKey(1);
        System.out.println(user);
        User user3=new User();
        user3.setUsername("123");
        userMapper.insert(user3);
        User user2=userMapper.selectByPrimaryKey(1);
        System.out.println(user2);
    }

咱們能夠看到,在修改操做後執行的相同查詢,查詢了數據庫,一級緩存失效。分析:若是是insert/delete/update方法,緩存就會刷新

一級緩存總結:
一、Mybatis一級緩存的生命週期和SqlSession一致。
二、Mybatis的緩存是一個粗粒度的緩存,沒有更新緩存和緩存過時的概念,同時只是使用了默認的hashmap,也沒有作容量上的限定。
三、Mybatis的一級緩存最大範圍是SqlSession內部,有多個SqlSession或者分佈式的環境下,有操做數據庫寫的話,會引發髒數據,建議是把一級緩存的默認級別設定爲Statement,即不使用一級緩存。
 

文章參考:https://www.jianshu.com/p/c553169c5921

相關文章
相關標籤/搜索