mybatis 二級(jí)cache

一:mybatis 介紹cache和使用cache


mybatis自帶的緩存構(gòu)架愚争,方便配置、功能強(qiáng)大捅彻、定制方便步淹。默認(rèn)情況下cache是沒(méi)有被開啟的缭裆。想要開啟此功能需要在sql映射文件中添加這樣一行:
<cache />

添加這一行后,會(huì)產(chǎn)生如下效果:
  • 映射語(yǔ)句文件中的所有select 語(yǔ)句將會(huì)被緩存韧衣。
  • 映射語(yǔ)句文件中的所有insert,update 和delete 語(yǔ)句會(huì)刷新緩存畅铭。
  • 緩存會(huì)使用Least Recently Used(LRU,最近最少使用的)算法來(lái)收回勃蜘。
  • 根據(jù)時(shí)間表(比如no Flush Interval,沒(méi)有刷新間隔), 緩存不會(huì)以任何時(shí)間順序來(lái)刷新炉擅。
  • 緩存會(huì)存儲(chǔ)列表集合或?qū)ο?無(wú)論查詢方法返回什么)的1024 個(gè)引用谍失。
  • 緩存會(huì)被視為是read/write(可讀/可寫)的緩存,意味著對(duì)象檢索不是共享的,而且可以安全地被調(diào)用者修改,而不干擾其他調(diào)用者或線程所做的潛在修改莹汤。

以上所有的屬性都可以通過(guò)<cache /> 元素來(lái)修改:

  <cache
    eviction="FIFO"http://回收策略
    flushInterval="60000"http://刷新間隔
    size="512"http://引用數(shù)目
    readOnly="true"http://只讀
  />

以上表明首先創(chuàng)建了一個(gè)先進(jìn)先出策略的緩存,并每隔 60 秒刷新,存數(shù)結(jié)果對(duì)象或列表的 512 個(gè)引用,而且返回的對(duì)象被認(rèn)為是只讀的,因此在不同線程中的調(diào)用者之間修改它們會(huì)導(dǎo)致沖突快鱼。

可用的收回策略有:
  • LRU – 最近最少使用的:移除最長(zhǎng)時(shí)間不被使用的對(duì)象。
  • FIFO – 先進(jìn)先出:按對(duì)象進(jìn)入緩存的順序來(lái)移除它們纲岭。
  • SOFT – 軟引用:移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對(duì)象抹竹。
  • WEAK – 弱引用:更積極地移除基于垃圾收集器狀態(tài)和弱引用規(guī)則的對(duì)象。
    默認(rèn)的是LRU止潮。

屬性flushInterval(刷新間隔)可以被設(shè)置為任意的正整數(shù),而且它們代表一個(gè)合理的毫秒形式的時(shí)間段窃判。默認(rèn)情況是不設(shè)置,也就是沒(méi)有刷新間隔,緩存僅僅調(diào)用語(yǔ)句時(shí)刷新。

屬性size(引用數(shù)目)可以被設(shè)置為任意正整數(shù),要記住你緩存的對(duì)象數(shù)目和你運(yùn)行環(huán)境的可用內(nèi)存資源數(shù)目喇闸。默認(rèn)值是1024袄琳。

屬性readOnly(只讀)屬性可以被設(shè)置為true 或 false雳殊。只讀的緩存會(huì)給所有調(diào)用者返回緩存對(duì)象的相同實(shí)例痢艺。因此這些對(duì)象不能被修改。這提供了很重要的性能優(yōu)勢(shì)箕戳〗檠溃可讀寫的緩存會(huì)返回緩存對(duì)象的拷貝(通過(guò)序列化) 。這會(huì)慢一些,但是安全,因此默認(rèn)是false。

<select />標(biāo)簽中關(guān)于緩存的使用
屬性

flushCache:將其設(shè)置為 true,任何時(shí)候只要語(yǔ)句被調(diào)用,都會(huì)導(dǎo)致本地緩存和二級(jí)緩存都會(huì)被清空粱哼,默認(rèn)值:false。
useCache:將其設(shè)置為 true,將會(huì)導(dǎo)致本條語(yǔ)句的結(jié)果被二級(jí)緩存,默認(rèn)值:對(duì) select 元素為 true。如果設(shè)置為false盈蛮,那么即使啟用了<cache />該條select的結(jié)構(gòu)也不會(huì)被二級(jí)緩存寸五。

二:下面結(jié)合springMVC+mybatis+mysql實(shí)際檢驗(yàn)


數(shù)據(jù)表(user)
數(shù)據(jù)表(user)
模擬正常情況:
返回結(jié)果
返回結(jié)果
  • console輸出:

1.對(duì)比已有緩存的命中是0.0,所以從數(shù)據(jù)庫(kù)中fetch數(shù)據(jù),產(chǎn)生一次數(shù)據(jù)庫(kù)查詢。


第一次請(qǐng)求的console顯示
第一次請(qǐng)求的console顯示

2.緊接著第二次請(qǐng)求,從緩存中對(duì)比,比率是0.5憨琳,達(dá)到mybatis設(shè)定的范圍问拘,返回緩存數(shù)據(jù),沒(méi)有產(chǎn)生數(shù)據(jù)庫(kù)查詢。


第二次請(qǐng)求的console顯示
第二次請(qǐng)求的console顯示

3.過(guò)了60秒后請(qǐng)求辖佣,從緩存中對(duì)比世蔗,比率是0.33333333,沒(méi)有達(dá)到mybatis設(shè)定的范圍赁豆,從數(shù)據(jù)庫(kù)中fetch數(shù)據(jù),產(chǎn)生一次數(shù)據(jù)庫(kù)查詢甲抖。如果從cache標(biāo)簽中去掉flushInterval屬性,該查詢結(jié)果將始終走緩存,只當(dāng)在項(xiàng)目中發(fā)送delete哲戚、update脆炎、insert操作時(shí)才會(huì)更新緩存几蜻。


第三次請(qǐng)求的console顯示
第三次請(qǐng)求的console顯示
非正常情況:
返回結(jié)果
返回結(jié)果

1.第一次請(qǐng)求正常輸出=>手動(dòng)從數(shù)據(jù)庫(kù)刪除數(shù)據(jù)粱栖、從另一個(gè)項(xiàng)目更改數(shù)據(jù)=>第二次查詢=>返回結(jié)果 手動(dòng)刪除:DELETE FROM user WHERE username = '經(jīng)紀(jì)人1'

刪除后的數(shù)據(jù)結(jié)果
刪除后的數(shù)據(jù)結(jié)果

2.第二次請(qǐng)求后輸出結(jié)果


手動(dòng)刪除數(shù)據(jù)庫(kù)后价认,返回的結(jié)果
手動(dòng)刪除數(shù)據(jù)庫(kù)后渠退,返回的結(jié)果
  • console輸出:
非正常情況下碎乃,查詢后console的顯示
非正常情況下,查詢后console的顯示

這樣就出現(xiàn)了臟數(shù)據(jù)证九!

三:mybatis緩存使用注意事項(xiàng)


如果數(shù)據(jù)緩存在本地拥坛,另一個(gè)系統(tǒng)修改數(shù)據(jù)庫(kù)或者手動(dòng)修改數(shù)據(jù)庫(kù)時(shí)谍咆,會(huì)出現(xiàn)臟數(shù)據(jù)問(wèn)題。

  • 一級(jí)緩存
    Myatis的一級(jí)緩存默認(rèn)為SESSION,底層用PerpetualCache,里面使用map做為存儲(chǔ),并沒(méi)有做太多條件限制罩阵。

  • 二級(jí)緩存
    MyBatis雖然全局配置開啟緩存喧笔,但是還是取決于是否使用了<cache/>標(biāo)簽割按,如果使用了二級(jí)緩存膨报,需要注意:
    每個(gè)<cache />代表一個(gè)單獨(dú)的二級(jí)緩存,如果多個(gè)Mapper需要共享同一個(gè)二級(jí)緩存适荣,就需要使用<cache-ref/>如果一個(gè)Mapper中查詢數(shù)據(jù)時(shí)丙躏,使用了多表聯(lián)查,當(dāng)另一個(gè)Mapper更新相關(guān)數(shù)據(jù)時(shí)束凑,如果沒(méi)有共享一個(gè)Cache,那么下一次該Mapper查詢時(shí)栅盲,就會(huì)出現(xiàn)讀到臟數(shù)據(jù)汪诉。

  • 使用二級(jí)緩存一般基于以下原則:
    不經(jīng)常變動(dòng)的數(shù)據(jù),但經(jīng)常會(huì)使用
    數(shù)據(jù)量比較大,系統(tǒng)多處會(huì)用到扒寄∮愎模或者跨系統(tǒng)用。
    對(duì)性能有特別要求的地方该编。
    濫用二級(jí)緩存迄本,有可能反而會(huì)降低性能,特別是根據(jù)條件查詢緩存课竣。

四:源碼淺析

mybatis下關(guān)于cache的所有類
mybatis下關(guān)于cache的所有類
  • 包內(nèi)容淺析
    cache包下嘉赎,分為裝飾者包(其中有些關(guān)于cache的具體類文件,比如阻塞加鎖cache的委派于樟、fifo的cache委派公条,使用裝飾者模式起到了在不同使用場(chǎng)景靈活委派功能的目的,具有良好的擴(kuò)展性)和cache底層實(shí)現(xiàn)包迂曲,以上類都實(shí)現(xiàn)了Cache接口靶橱。
  • 調(diào)用順序:
    mybatis的關(guān)于cache有個(gè)CacheBuilder類,該類使用建造者模式路捧,在其中有個(gè)public Cache build()方法負(fù)責(zé)具體的<cache />屬性的組裝关霸。通過(guò)MapperBuilderAssistant類調(diào)用CacheBuilder進(jìn)行具體的裝配順序操作。
CacheBuilder類
CacheBuilder類

CacheBuilder類
CacheBuilder類

MapperBuilderAssistant類
MapperBuilderAssistant類

MapperAnnotationBuilder類(負(fù)責(zé)處理mybatis的注解)
MapperAnnotationBuilder類(負(fù)責(zé)處理mybatis的注解)

XMLMapperBuilder類(負(fù)責(zé)處理mybatismapper的xml)
XMLMapperBuilder類(負(fù)責(zé)處理mybatismapper的xml)

五:mybatis2級(jí)緩存機(jī)制杰扫、涉及的設(shè)計(jì)模式


百字不如一圖

mybatis緩存機(jī)制.png

裝飾者模式

裝飾者模式在不必改變?cè)愇募褪褂美^承的情況下队寇,動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對(duì)象的功能。它是通過(guò)創(chuàng)建一個(gè)包裝類的對(duì)象涉波,也就是裝飾來(lái)包裹真實(shí)的對(duì)象英上。

裝飾者模式
  • 執(zhí)行main()方法
public class Go {

    public static void main(String[] args) {

        System.out.println("套餐菜單\n");

        EggsNoodles eggsNoodles = new EggsNoodles();
        eggsNoodles.noodNameAndPrice();

        DecoratorNoodles decoratorNoodles = new BeefNoodles(eggsNoodles);
        decoratorNoodles.noodNameAndPrice();

        DecoratorNoodles decoratorNoodles1 = new AubergineNoodles(eggsNoodles);
        decoratorNoodles1.noodNameAndPrice();

        DecoratorNoodles decoratorNoodles2 = new AubergineNoodles(decoratorNoodles);
        decoratorNoodles2.noodNameAndPrice();
    }
}
運(yùn)行結(jié)果

六:mybatis cache作用


mybatis cache 提供查詢緩存,用于減輕數(shù)據(jù)庫(kù)壓力啤覆,提高數(shù)據(jù)庫(kù)性能苍日。快速響應(yīng)用戶請(qǐng)求窗声,改善用戶體驗(yàn)相恃。適用于各種頻繁查詢數(shù)據(jù)且查詢條件不是十分復(fù)雜的業(yè)務(wù)。

需要源碼請(qǐng)留下郵箱

參考官方文檔:
http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#Auto-mapping

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末笨觅,一起剝皮案震驚了整個(gè)濱河市拦耐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌见剩,老刑警劉巖杀糯,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異苍苞,居然都是意外死亡固翰,警方通過(guò)查閱死者的電腦和手機(jī)狼纬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)骂际,“玉大人疗琉,你說(shuō)我怎么就攤上這事∏嘎粒” “怎么了盈简?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)太示。 經(jīng)常有香客問(wèn)我柠贤,道長(zhǎng),這世上最難降的妖魔是什么先匪? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任种吸,我火速辦了婚禮,結(jié)果婚禮上呀非,老公的妹妹穿的比我還像新娘坚俗。我一直安慰自己,他們只是感情好岸裙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布猖败。 她就那樣靜靜地躺著,像睡著了一般降允。 火紅的嫁衣襯著肌膚如雪恩闻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天剧董,我揣著相機(jī)與錄音幢尚,去河邊找鬼。 笑死翅楼,一個(gè)胖子當(dāng)著我的面吹牛尉剩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播毅臊,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼理茎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了管嬉?” 一聲冷哼從身側(cè)響起皂林,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蚯撩,沒(méi)想到半個(gè)月后础倍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胎挎,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年沟启,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扰楼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡美浦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出项栏,到底是詐尸還是另有隱情浦辨,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布沼沈,位于F島的核電站流酬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏列另。R本人自食惡果不足惜芽腾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望页衙。 院中可真熱鬧摊滔,春花似錦、人聲如沸店乐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)眨八。三九已至腺兴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間廉侧,已是汗流浹背页响。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留段誊,地道東北人闰蚕。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像枕扫,于是被迫代替她去往敵國(guó)和親陪腌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容