Mybatis緩存配置—— 二級緩存


一、配置二級緩存

1. 在mybatis_config.xml中進行如下配置:

<setting name="cacheEnabled" value="true"/>

其實這里的二級緩存默認是出於開啟狀態,因此這個位置可以不進行配置,知道有這么回事兒即可。

2.MyBatis二級緩存是和命名空間是綁定的 ,即二級緩存需要配置在 Mapper.xml 映射文件中,或者配置在 Mapper.java 接口中。在映射文件中命名空間就是 XML 根節點 mapper namespace 屬性 Mapper 接口中,命名空間就是接口的全限定名稱。

(1)在RoleMapper.xml中進行二級緩存配置,添加配置如下:

<?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.example.simple.mapper.RoleMapper">
    <cache
    eviction="FIFO"
    flushInterval="6000"
    size="512"
    readOnly="false"/>
/mapper>

(2)在RoleMapper.java類中添加注解:

@CacheNamespaceRef(RoleMapper.class)
public interface RoleMapper {
//代碼
}

最基本的二級緩存就配置好了。

二、使用二級緩存

  上面的配置是可讀寫的緩存,而 MyBatis使用 SerializedCache序列化緩存來實現可讀寫緩存類,井通過序列化和反序列化來保證通過緩存獲取數據時,得到的是一個新的實例。因此,如果配置為只讀緩存,Mybatis就會使用 Map 來存儲緩存值,這種情況下 ,從緩存中獲取的對象就是同一個實例。

1. 因為使用可讀寫緩存,可以使用 SerializedCache 序列 緩存。這個緩存類要求所有被序列化的對象必須實現 Serializable (java.io.Serializable )接口,所以還需要修改 SysRole 對象 ,代碼如下:
public class SysRole implements Serializable
{

    private static final long serialVersionUID = 6320941908222932112L ;

    /*
    * 其他方法    * */
}

2. 編寫測試方法如下:

@Test
        public void testCache2(){
            SqlSession sqlSession = getSqlSession();
            SysRole role = null;
            try{
                RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
                role = roleMapper.selectById(1l);
                role.setRoleName("new name");
                SysRole role1 = roleMapper.selectById(1l);
                Assert.assertEquals(role1.getRoleName() , "new name");
                Assert.assertEquals(role,role1);

            }finally {
                sqlSession.close();
            }
            System.out.println("開啟新一個sqlSession" );
            sqlSession = getSqlSession();
            try{
                RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
                SysRole role1 = roleMapper.selectById(1l);
                Assert.assertEquals(role1.getRoleName(),"new name");
                Assert.assertNotEquals(role,role1);
                SysRole role2 = roleMapper.selectById(1l);
                Assert.assertNotEquals(role1,role2);
            }finally {

            }

        }

測試結果如下:

DEBUG [main] - Cache Hit Ratio [com.example.simple.mapper.RoleMapper]: 0.0
DEBUG [main] - ==> Preparing: select id, role_name,enabled,create_by,create_time from sys_role where id = ?
DEBUG [main] - ==> Parameters: 1(Long)
TRACE [main] - <== Columns: id, role_name, enabled, create_by, create_time
TRACE [main] - <== Row: 1, 管理員, 1, 1, 2020-12-01 20:05:01
DEBUG [main] - <== Total: 1
DEBUG [main] - Cache Hit Ratio [com.example.simple.mapper.RoleMapper]: 0.0
開啟新一個sqlSession
DEBUG [main] - Cache Hit Ratio [com.example.simple.mapper.RoleMapper]: 0.3333333333333333
DEBUG [main] - Cache Hit Ratio [com.example.simple.mapper.RoleMapper]: 0.5

解析:

  日志中存在好幾條以 Cache Hit Ratio 開頭的語句 ,這行日志后面輸出的值為當前執行方法的緩存命中率,在測試第一部分中,第一次查詢獲取 rolel 的時候由於沒有緩存,所以執

行了數據庫查詢。在第二個查詢獲取 role2 的時候, role2和rolel 是完全相同的實例,這里使用的是一級緩存,所以返回同一個實例。
  調用 close 方法關閉 SqlSession 時, SqlSession 才會保存查詢數據到二級緩存中,在這之后二級緩存才有了緩存數據,所以可以看到在第一部分的兩次查詢時,命中率都是0;在第二部分測試代碼中,再次獲取 role2 時,日志中並沒有輸出數據庫查詢,而是輸出了命中率,這時的命中率是 0.3333333333333333 ,這是第三次查詢,並且得到了緩存的值,因此該方法 共被請求了3次,有一次命中,所以命中率就是三分之一。 后面再獲取 role3 的時候,就是四次請求,兩次命中,命中率為 0.5 。並且因為可讀寫緩存的緣故, role2和role3 都是反序列化得到的結果 ,所以它們不是相同的實例,在這 部分,這兩個實例是讀寫安全的,其屬性不會互相影響。
三、二級緩存使用場景:
級緩存雖然好處很多,但並不是什么時候都可以使用在以下場景中,推薦使用二級緩存以查詢為主的應用中,只有盡可能少的增、刪、改操作,絕大多數以單表操作存在時,由於很少存在互相關聯的情況,因此不會出現臟數據可以按業務划分對表進行分組時,如關聯的表比較少,可以通過參照緩存進行配置。除了推薦使用的情況,如果臟讀對系統沒有影響,也可以考慮使用。在無法保證數據不出現臟讀的情況下,建議在業務層使用可控制的緩存代替二級緩存
  至此,告一段落。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM