MyBatis學(xué)習(xí)教程(七)-Mybatis緩存介紹
一、MyBatis緩存介紹
正如大多數(shù)持久層框架一樣,MyBatis 同樣提供了一級(jí)緩存和二級(jí)緩存的支持
1.一級(jí)緩存:
基于PerpetualCache 的 HashMap本地緩存,其存儲(chǔ)作用域?yàn)?Session,當(dāng) Session flush 或 close 之后,該Session中的所有 Cache 就將清空?!?/p>
2. 二級(jí)緩存:
二級(jí)緩存與一級(jí)緩存其機(jī)制相同,默認(rèn)也是采用 PerpetualCache,HashMap存儲(chǔ),不同在于其存儲(chǔ)作用域?yàn)?Mapper(Namespace),并且可自定義存儲(chǔ)源,如 Ehcache。
3. 對(duì)于緩存數(shù)據(jù)更新機(jī)制,當(dāng)某一個(gè)作用域(一級(jí)緩存Session/二級(jí)緩存Namespaces)的進(jìn)行了 C/U/D 操作后,默認(rèn)該作用域下所有 select 中的緩存將被clear。
1.1、Mybatis一級(jí)緩存測(cè)試
package me.gacl.test; import me.gacl.domain.User; import me.gacl.util.MyBatisUtil; import org.apache.ibatis.session.SqlSession; import org.junit.Test; /** * @author gacl * 測(cè)試一級(jí)緩存 */ public class TestOneLevelCache { /* * 一級(jí)緩存: 也就Session級(jí)的緩存(默認(rèn)開(kāi)啟) */ @Test public void testCache() { SqlSession session = MyBatisUtil.getSqlSession(); String statement = "me.gacl.mapping.userMapper.getUser"; User user = session.selectOne(statement, ); System.out.println(user); /* * 一級(jí)緩存默認(rèn)就會(huì)被使用 */ user = session.selectOne(statement, ); System.out.println(user); session.close(); /* . 必須是同一個(gè)Session,如果session對(duì)象已經(jīng)close()過(guò)了就不可能用了 */ session = MyBatisUtil.getSqlSession(); user = session.selectOne(statement, ); System.out.println(user); /* . 查詢條件是一樣的 */ user = session.selectOne(statement, ); System.out.println(user); /* . 沒(méi)有執(zhí)行過(guò)session.clearCache()清理緩存 */ //session.clearCache(); user = session.selectOne(statement, ); System.out.println(user); /* . 沒(méi)有執(zhí)行過(guò)增刪改的操作(這些操作都會(huì)清理緩存) */ session.update("me.gacl.mapping.userMapper.updateUser", new User(, "user", )); user = session.selectOne(statement, ); System.out.println(user); } }
1.2、Mybatis二級(jí)緩存測(cè)試
1、開(kāi)啟二級(jí)緩存,在userMapper.xml文件中添加如下配置
<mapper namespace="me.gacl.mapping.userMapper"> <!-- 開(kāi)啟二級(jí)緩存 --> <cache/>
2、測(cè)試二級(jí)緩存
package me.gacl.test; import me.gacl.domain.User; import me.gacl.util.MyBatisUtil; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.junit.Test; /** * @author gacl * 測(cè)試二級(jí)緩存 */ public class TestTwoLevelCache { /* * 測(cè)試二級(jí)緩存 * 使用兩個(gè)不同的SqlSession對(duì)象去執(zhí)行相同查詢條件的查詢,第二次查詢時(shí)不會(huì)再發(fā)送SQL語(yǔ)句,而是直接從緩存中取出數(shù)據(jù) */ @Test public void testCache() { String statement = "me.gacl.mapping.userMapper.getUser"; SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory(); //開(kāi)啟兩個(gè)不同的SqlSession SqlSession session = factory.openSession(); SqlSession session = factory.openSession(); //使用二級(jí)緩存時(shí),User類必須實(shí)現(xiàn)一個(gè)Serializable接口===> User implements Serializable User user = session.selectOne(statement, ); session.commit();//不懂為啥,這個(gè)地方一定要提交事務(wù)之后二級(jí)緩存才會(huì)起作用 System.out.println("user="+user); //由于使用的是兩個(gè)不同的SqlSession對(duì)象,所以即使查詢條件相同,一級(jí)緩存也不會(huì)開(kāi)啟使用 user = session.selectOne(statement, ); //session.commit(); System.out.println("user="+user); } }
1.3、二級(jí)緩存補(bǔ)充說(shuō)明
1. 映射語(yǔ)句文件中的所有select語(yǔ)句將會(huì)被緩存。
2. 映射語(yǔ)句文件中的所有insert,update和delete語(yǔ)句會(huì)刷新緩存。
3. 緩存會(huì)使用Least Recently Used(LRU,最近最少使用的)算法來(lái)收回。
4. 緩存會(huì)根據(jù)指定的時(shí)間間隔來(lái)刷新。
5. 緩存會(huì)存儲(chǔ)1024個(gè)對(duì)象
cache標(biāo)簽常用屬性:
<cache eviction="FIFO" <!--回收策略為先進(jìn)先出--> flushInterval="60000" <!--自動(dòng)刷新時(shí)間60s--> size="512" <!--最多緩存512個(gè)引用對(duì)象--> readOnly="true"/> <!--只讀-->
給大家補(bǔ)充點(diǎn)知識(shí):
和hibernate一樣,mybatis也有緩存機(jī)制
一級(jí)緩存是基于 PerpetualCache(mybatis自帶)的 HashMap 本地緩存,作用范圍為session,所以當(dāng)session commit或close后,緩存就會(huì)被清空
二級(jí)緩存默認(rèn)也是基于 PerpetualCache,但是可以為其制定存儲(chǔ)源,比如ehcache
一級(jí)緩存緩存的是SQL語(yǔ)句,而二級(jí)緩存緩存的是結(jié)果對(duì)象,看如下例子(mybatis的日志級(jí)別設(shè)為debug)
相關(guān)文章
SpringBoot中使用Guava實(shí)現(xiàn)單機(jī)令牌桶限流的示例
本文主要介紹了SpringBoot中使用Guava實(shí)現(xiàn)單機(jī)令牌桶限流的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(1)
下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你2021-07-07Java中執(zhí)行docker命令的實(shí)現(xiàn)示例
本文主要介紹了Java中執(zhí)行docker命令的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08Java中ConcurrentHashMap是如何實(shí)現(xiàn)線程安全
ConcurrentHashMap是一個(gè)哈希表,支持檢索的全并發(fā)和更新的高預(yù)期并發(fā)。本文主要介紹了Java中ConcurrentHashMap是如何實(shí)現(xiàn)線程安全,感興趣的可以了解一下2021-11-11SpringBoot整合mybatis常見(jiàn)問(wèn)題(小結(jié))
這篇文章主要介紹了SpringBoot整合mybatis常見(jiàn)問(wèn)題(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Java中PriorityQueue實(shí)現(xiàn)最小堆和最大堆的用法
很多時(shí)候都會(huì)遇到PriorityQueue,本文主要介紹了Java中PriorityQueue實(shí)現(xiàn)最小堆和最大堆的用法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06Java實(shí)現(xiàn)多數(shù)據(jù)源的幾種方式總結(jié)
這篇文章主要給大家總結(jié)介紹了關(guān)于Java實(shí)現(xiàn)多數(shù)據(jù)源的幾種方式,最近項(xiàng)目中的工作流需要查詢多個(gè)數(shù)據(jù)源的數(shù)據(jù),數(shù)據(jù)源可能是不同種類的,需要的朋友可以參考下2023-08-08