天天看點

MyBatis 自帶二級緩存

mybatis 的兩種緩存機制:一級緩存和二級緩存

  • 一級緩存,又稱之為本地緩存,sqlSession級别的緩存,一級緩存是一直開啟的;SqlSession級别的一個Map;與資料庫同一次會話期間查詢到的資料會放在本地緩存中。 以後如果需要擷取相同的資料,直接從緩存中拿,沒必要再去查詢資料庫;

 一級緩存失效情況(沒有使用到目前一級緩存的情況,效果就是,還需要再向資料庫發出查詢):

     1、sqlSession不同。

     2、sqlSession相同,查詢條件不同.(目前一級緩存中還沒有這個資料)

     3、sqlSession相同,兩次查詢之間執行了增删改操作(這次增删改可能對目前資料有影響)

     4、sqlSession相同,手動清除了一級緩存(緩存清空)

@Test
public void testFirstLevelCache() throws IOException {
    SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
    SqlSession openSession = sqlSessionFactory.openSession();
    try{
       EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
       Employee emp01 = mapper.getEmpById(1);
       System.out.println(emp01);

       //1、sqlSession不同。
       //SqlSession openSession2 = sqlSessionFactory.openSession();
       //EmployeeMapper mapper2 = openSession2.getMapper(EmployeeMapper.class);
            
       //2、sqlSession相同,查詢條件不同
            
       //3、sqlSession相同,兩次查詢之間執行了增删改操作(這次增删改可能對目前資料有影響)
       //mapper.addEmp(new Employee(null, "testCache", "cache", "1"));
       //System.out.println("資料添加成功");
            
       //4、sqlSession相同,手動清除了一級緩存(緩存清空)
       //openSession.clearCache();
            
       Employee emp02 = mapper.getEmpById(1);
       //Employee emp03 = mapper.getEmpById(3);
       System.out.println(emp02);
       //System.out.println(emp03);
       System.out.println(emp01==emp02);
            
       //openSession2.close();
    }finally{
       openSession.close();
    }
}
           
  • 二級緩存,又稱為全局緩存,基于namespace級别的緩存:一個namespace對應一個二級緩存;

工作機制:

1、一個會話,查詢一條資料,這個資料就會被放在目前會話的一級緩存中;

2、如果會話關閉;一級緩存中的資料會被儲存到二級緩存中;新的會話查詢資訊,就可以參照二級緩存中的内容;

3、不同namespace查出的資料會放在自己對應的緩存中(map),資料會從二級緩存中擷取,查出的資料都會被預設先放在一級緩存中,隻有會話送出或者關閉以後,一級緩存中的資料才會轉移到二級緩存中。

二級緩存的使用:

1、開啟全局二級緩存配置:<setting name="cacheEnabled" value="true"/>

2、去xxxMapper.xml中配置使用二級緩存:<cache></cache>

3、POJO類需要實作序列化接口

<?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.gh.user.dao.EmployeeMapper">

    <!-- 使用第三方緩存 ehcache —>
    <cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
    <!-- 
    <cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"></cache> 
    -->
    <!--  cache 中各屬性的含義
    eviction:緩存的回收政策:
        • LRU – 最近最少使用的:移除最長時間不被使用的對象。
        • FIFO – 先進先出:按對象進入緩存的順序來移除它們。
        • SOFT – 軟引用:移除基于垃圾回收器狀态和軟引用規則的對象。
        • WEAK – 弱引用:更積極地移除基于垃圾收集器狀态和弱引用規則的對象。
        • 預設的是 LRU。
    flushInterval:緩存重新整理間隔  緩存多長時間清空一次,預設不清空,設定一個毫秒值
    readOnly:是否隻讀
        true:隻讀;mybatis認為所有從緩存中擷取資料的操作都是隻讀操作,不會修改資料。
              mybatis為了加快擷取速度,直接就會将資料在緩存中的引用交給使用者。不安全,速度快
        false:非隻讀:mybatis覺得擷取的資料可能會被修改。
               mybatis會利用序列化&反序列的技術克隆一份新的資料給你。安全,速度慢
    size:緩存存放多少元素;
    type="":指定自定義緩存的全類名;
            實作Cache接口即可;
    -->

    <select id="getEmpById" resultType="com.gh.user.po.Employee"
        databaseId="mysql" useCache="true">
        select * from tbl_employee where id = #{id}
    </select>
</mapper>
           
  • 和緩存有關的設定/屬性:

1、cacheEnabled=true:false:關閉緩存(二級緩存關閉)(一級緩存一直可用的)

2、每個select标簽都有useCache="true";  false:不使用緩存(一級緩存依然使用,二級緩存不使用)

3、每個增删改标簽的:flushCache="true":(一級二級都會清除)

4、sqlSession.clearCache();隻是清除目前session的一級緩存;

5、localCacheScope:本地緩存作用域:(預設 SESSION);目前會話的所有資料儲存在會話緩存中;STATEMENT:可以禁用一級緩存; 

  • 通常,二級緩存的使用,我們都會接入第三方緩存架構,比如ehcache,也可以自己定義自己的緩存政策,隻需要實作 mybatis 的 Cache 接口即可。

此文主要講解的是 對 mybatis 兩種級别的緩存了解與認識,接入第三方緩存的使用暫不贅述。

如有興趣的,可以參考官網位址:https://github.com/mybatis/spring-boot-starter

繼續閱讀