Mybatis緩存

MyBatis提供查詢緩存,如果緩存中有數(shù)據(jù)作烟,則直接從緩存中獲取,沒有則從數(shù)據(jù)庫查詢砾医,用以減輕數(shù)據(jù)壓力拿撩,提高系統(tǒng)性能。MyBatis的緩存分為一級(jí)緩存和二級(jí)緩存如蚜,默認(rèn)情況下一級(jí)緩存是開啟的压恒,且是不能關(guān)閉的。一級(jí)緩存是SqlSession級(jí)別的错邦,當(dāng)同一個(gè) SqlSession中進(jìn)行相同的sql查詢時(shí)探赫,第二次以后的查詢都是從一級(jí)緩存中獲取,一級(jí)緩存最多緩存1024條sql撬呢。二級(jí)緩存是Mapper級(jí)別的伦吠,可以跨SqlSession,不同SqlSession可共享。

MyBatis緩存機(jī)制

MyBatis緩存機(jī)制.png

MyBatis緩存實(shí)現(xiàn)原理

Executor接口.png

MyBatis認(rèn)為的完全相同的查詢魂拦,只要保證statementId毛仪,rowBounds,最后生成的SQL語句,以及這個(gè)SQL語句所需要的參數(shù)完全一致就可以了晨另。

一級(jí)緩存

一級(jí)緩存是如何組織的潭千?

一級(jí)緩存是SqlSession級(jí)別的緩存。在操作數(shù)據(jù)庫時(shí)需要構(gòu)造 sqlSession對(duì)象借尿,并為SqlSession對(duì)象創(chuàng)建一個(gè)Executor執(zhí)行器刨晴,而緩存信息以HashMap的形式維護(hù)在這個(gè)Executor中,MyBatis將緩存和緩存操作封裝在Cache中路翻。


SqlSession對(duì)象狈癞、Executor對(duì)象、Cache對(duì)象之間的關(guān)系.png

一級(jí)緩存原理

第一次發(fā)出一個(gè)查詢sql,sql查詢結(jié)果寫入SqlSession的一級(jí)緩存中茂契,緩存使用的數(shù)據(jù)結(jié)構(gòu)為(HashMap)蝶桶。
同一個(gè)SqlSession發(fā)出第二次查詢時(shí),就從緩存中獲取掉冶。如果兩次中間出現(xiàn)commit操作(update/insert/delete)真竖,則本SqlSession的一級(jí)緩存全部清空(為了緩存中記錄最新的數(shù)據(jù),避免臟讀)厌小,從數(shù)據(jù)庫查詢恢共。

  • key:mapperID+offset+limit+Sql+所有的入?yún)?/strong>
  • value:查詢結(jié)果

一級(jí)緩存的生命周期

  1. 開啟數(shù)據(jù)庫會(huì)話,創(chuàng)建新的SqlSession對(duì)象璧亚,SqlSession對(duì)象中會(huì)有一個(gè)Executor對(duì)象讨韭,Executor對(duì)象持有新的PerpetualCache對(duì)象;會(huì)話結(jié)束時(shí),SqlSession對(duì)象以及Executor對(duì)象和PerpetualCache對(duì)象一并銷毀透硝。
  2. SqlSession調(diào)用close()方法狰闪,會(huì)釋放掉一級(jí)緩存PerpetualCache對(duì)象,一級(jí)緩存不可用濒生。
  3. 如果SqlSession調(diào)用clearCache()方法埋泵,會(huì)清空PerpetualCache對(duì)象,但對(duì)象仍可用甜攀。
  4. SqlSession執(zhí)行任何一個(gè)insert()秋泄、update()琐馆、delete()操作,會(huì)清空PerpetualCache對(duì)象规阀,但對(duì)象仍可用。

一級(jí)緩存的工作流程

  1. 對(duì)于某個(gè)查詢瘦麸,根據(jù)statementId谁撼、params、rowBounds來構(gòu)建key值滋饲,根據(jù)key值去緩存Cache中查找結(jié)果厉碟;
  2. 判斷從Cache中根據(jù)特定的key值取的數(shù)據(jù)數(shù)據(jù)是否為空,即是否命中屠缭;
  3. 如果命中箍鼓,則直接返回查詢結(jié)果;
  4. 如果沒有命中:
  • 數(shù)據(jù)庫中查詢結(jié)果呵曹;
  • 將key和查詢結(jié)果分別作為key和value存入Cache緩存中款咖;
  • 查詢結(jié)果返回。
  1. 結(jié)束奄喂。

一級(jí)緩存性能分析

  1. Session級(jí)別的一級(jí)緩存設(shè)計(jì)比較簡單铐殃,只使用了HashMap來維護(hù),并沒有對(duì)HashMap的容量和大小進(jìn)行限制跨新。
  • SqlSession的生存時(shí)間很短富腊。使用一個(gè)SqlSession對(duì)象執(zhí)行的操作不會(huì)太多,執(zhí)行完就會(huì)消亡域帐;
  • 對(duì)于某一個(gè)SqlSession對(duì)象而言赘被,只要執(zhí)行commit操作(update、insert肖揣、delete)民假,都會(huì)將這個(gè)SqlSession對(duì)象中對(duì)應(yīng)的一級(jí)緩存清空掉,所以一般情況下不會(huì)出現(xiàn)緩存過大许饿,影響JVM內(nèi)存空間的問題阳欲;
  • 可以手動(dòng)地釋放掉SqlSession對(duì)象中的緩存。
  1. 一級(jí)緩存是粗粒度緩存,沒有更新緩存和緩存過期概念球化。
  • 對(duì)于數(shù)據(jù)變化頻率很大秽晚,并且需要高時(shí)效準(zhǔn)確性的數(shù)據(jù)要求,我們使用SqlSession查詢的時(shí)候筒愚,要控制好SqlSession的生存時(shí)間赴蝇,SqlSession的生存時(shí)間越長,它其中緩存的數(shù)據(jù)有可能就越舊巢掺,從而造成和真實(shí)數(shù)據(jù)庫的誤差句伶;同時(shí)對(duì)于這種情況,用戶也可以手動(dòng)地適時(shí)清空SqlSession中的緩存陆淀;
  • 對(duì)于只執(zhí)行考余、并且頻繁執(zhí)行大范圍的select操作的SqlSession對(duì)象,SqlSession對(duì)象的生存時(shí)間不應(yīng)過長轧苫。

二級(jí)緩存

二級(jí)緩存是mapper級(jí)別的楚堤,mapper以命名空間為單位創(chuàng)建緩存數(shù)據(jù)結(jié)構(gòu)(HashMap),二級(jí)緩存通過CachingExecutor(Executor的代理對(duì)象)實(shí)現(xiàn)。

二級(jí)緩存原理

所有查詢操作含懊,在CachingExecutor都會(huì)先匹配緩存中是否存在身冬,否則查詢數(shù)據(jù)庫。

  • key:mapperID+offset+limit+Sql+所有的入?yún)?/strong>
  • value:查詢結(jié)果

二級(jí)緩存工作模式

二級(jí)緩存機(jī)制關(guān)鍵在于Executor對(duì)象岔乔。若配置【cacheEnable=true】酥筝,則為SqlSession創(chuàng)建Executor加上一個(gè)裝飾者(CachingExecutor)。這時(shí)由CachingExecutor對(duì)象來完成操作請(qǐng)求雏门。
CachingExecutor對(duì)于查詢請(qǐng)求嘿歌,先判斷在Application級(jí)別的二級(jí)緩存是否有結(jié)果,如果有直接返回結(jié)果剿配。若沒有搅幅,再交給真正的Executor對(duì)象來完成查詢,之后CachingExecutor會(huì)將真正Executor返回的結(jié)果放置在緩存中呼胚,在返回給用戶茄唐。


使用二級(jí)緩存工作模式.png

二級(jí)緩存劃分

MyBatis并不簡單將Application就只有一個(gè)Cache緩存對(duì)象,它將緩存劃分的更新蝇更,即是mapper級(jí)別的(即每一個(gè)mapper一個(gè)緩存對(duì)象)沪编。

1. 為每一個(gè)mapper分配一個(gè)緩存對(duì)象(對(duì)于每一個(gè)mapper.xml,在其中使用<cache> 節(jié)點(diǎn))。

使用cache節(jié)點(diǎn)配置.png

2. 多個(gè)mapper共用一個(gè)緩存對(duì)象(使用<cache-ref namespace="">節(jié)點(diǎn)年扩,來指定你的這個(gè)Mapper使用到了哪一個(gè)Mapper的Cache緩存)蚁廓。

cache-ref共用緩存.png

二級(jí)緩存的開啟

MyBatis對(duì)二級(jí)緩存的支持粒度較細(xì),需要具體指定到某條查詢語句上厨幻。如果要開啟二級(jí)緩存相嵌,需做到如下三點(diǎn):

  1. MyBatis支持二級(jí)緩存的總開關(guān):全局配置變量參數(shù)【cacheEnabled=true】腿时。
  2. 該select語句所在的Mapper,配置了<cache> 或<cached-ref>節(jié)點(diǎn)饭宾,并且有效批糟。
  3. 該select語句的參數(shù) useCache=true。

二級(jí)緩存的實(shí)現(xiàn)

MyBatis 對(duì)于二級(jí)緩存的實(shí)現(xiàn)非常靈活看铆,自己內(nèi)部實(shí)現(xiàn)了Cache的一系列的實(shí)現(xiàn)類徽鼎,并提供了各種緩存刷新策略LRU、FIFO等弹惦。同時(shí)它也允許自定義Cache接口實(shí)現(xiàn)否淤,需實(shí)現(xiàn)org.apache.ibatis.cache.Cache接口,然后將Cache的實(shí)現(xiàn)類配置在<cache type="">節(jié)點(diǎn)的type屬性上棠隐。此外石抡,它也支持與第三方緩存庫如Memecached的集成。

二級(jí)緩存的實(shí)現(xiàn)有三種選擇:

  1. MyBatis自身提供的緩存實(shí)現(xiàn)宵荒;

    • MyBatis定義了大量的Cache的裝飾器來增強(qiáng)Cache緩存的功能


      Cache裝飾器.png
    • 對(duì)于每個(gè)Cache而言汁雷,都有容量限制净嘀,MyBatis提供了各種策略來對(duì)Cache緩存的容量進(jìn)行控制报咳,以及對(duì)于Cache中的數(shù)據(jù)進(jìn)行刷新和置換。主要有以下幾個(gè)刷新和置換策略:

      LRU:Least Recently Used,最近最少使用算法挖藏,即緩存中容量滿了暑刃,會(huì)將緩存最近最少使用的數(shù)據(jù)清楚,添加上新的記錄膜眠。

      FIFO:First In First Out,先進(jìn)先出算法岩臣,即緩存中容量滿了,會(huì)將最先進(jìn)來的數(shù)據(jù)清楚。

      Scheduled:指定時(shí)間間隔清空算法宵膨,該算法會(huì)以指定的某一個(gè)時(shí)間間隔將Cache緩存中的數(shù)據(jù)清空架谎。

  2. 用戶自定義的Cache接口實(shí)現(xiàn);

  3. 跟第三方內(nèi)存緩存庫的集成辟躏;

二級(jí)緩存應(yīng)用場景

  • 使用場景
    對(duì)于訪問響應(yīng)速度要求高谷扣,但是實(shí)時(shí)性不高的查詢,可以采用二級(jí)緩存技術(shù)捎琐。
  • 注意事項(xiàng)
    在使用二級(jí)緩存的時(shí)候会涎,要設(shè)置一下刷新間隔(cache標(biāo)簽中有一個(gè)flashInterval屬性)來定時(shí)刷新二級(jí)緩存,這個(gè)刷新間隔根據(jù)具體需求來設(shè)置瑞凑,比如設(shè)置30分鐘末秃、60分鐘等,單位為毫秒籽御。

二級(jí)緩存局限性

Mybatis二級(jí)緩存對(duì)細(xì)粒度的數(shù)據(jù)級(jí)別的緩存實(shí)現(xiàn)不好练慕。

  • 場景
    對(duì)商品信息進(jìn)行緩存惰匙,由于商品信息查詢?cè)L問量大,但是要求用戶每次查詢都是最新的商品信息铃将,此時(shí)如果使用二級(jí)緩存徽曲,就無法實(shí)現(xiàn)當(dāng)一個(gè)商品發(fā)生變化只刷新該商品的緩存信息而不刷新其他商品緩存信息,因?yàn)槎?jí)緩存是mapper級(jí)別的麸塞,當(dāng)一個(gè)商品的信息發(fā)送更新秃臣,所有的商品信息緩存數(shù)據(jù)都會(huì)清空。

  • 解決方法
    此類問題哪工,需要在業(yè)務(wù)層根據(jù)需要對(duì)數(shù)據(jù)有針對(duì)性的緩存奥此。
    比如可以對(duì)經(jīng)常變化的 數(shù)據(jù)操作單獨(dú)放到另一個(gè)namespace的mapper中。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末雁比,一起剝皮案震驚了整個(gè)濱河市稚虎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌偎捎,老刑警劉巖蠢终,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異茴她,居然都是意外死亡寻拂,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門丈牢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來祭钉,“玉大人,你說我怎么就攤上這事己沛』藕耍” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵申尼,是天一觀的道長垮卓。 經(jīng)常有香客問我,道長师幕,這世上最難降的妖魔是什么粟按? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮们衙,結(jié)果婚禮上钾怔,老公的妹妹穿的比我還像新娘。我一直安慰自己蒙挑,他們只是感情好宗侦,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著忆蚀,像睡著了一般矾利。 火紅的嫁衣襯著肌膚如雪姑裂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天男旗,我揣著相機(jī)與錄音舶斧,去河邊找鬼。 笑死察皇,一個(gè)胖子當(dāng)著我的面吹牛茴厉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播什荣,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼矾缓,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了稻爬?” 一聲冷哼從身側(cè)響起嗜闻,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎桅锄,沒想到半個(gè)月后琉雳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡友瘤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年翠肘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片商佑。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锯茄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茶没,到底是詐尸還是另有隱情,我是刑警寧澤晚碾,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布抓半,位于F島的核電站,受9級(jí)特大地震影響格嘁,放射性物質(zhì)發(fā)生泄漏笛求。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一糕簿、第九天 我趴在偏房一處隱蔽的房頂上張望探入。 院中可真熱鬧,春花似錦懂诗、人聲如沸蜂嗽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽植旧。三九已至辱揭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間病附,已是汗流浹背问窃。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留完沪,地道東北人域庇。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像覆积,于是被迫代替她去往敵國和親较剃。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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

  • 緩存技術(shù)是一種“以空間換時(shí)間”的設(shè)計(jì)理念技健,是利用內(nèi)存空間資源來提高數(shù)據(jù)檢索速度的有效手段之一写穴。Mybatis包含一...
    不知名的蛋撻閱讀 4,060評(píng)論 0 7
  • 一級(jí)緩存 MyBatis 包含了一個(gè)非常強(qiáng)大的查詢緩存特性,它可以非常方便地配置和定制。MyBatis 3 中的緩...
    SuBHFeng閱讀 314評(píng)論 0 0
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月雌贱,有人笑有人哭啊送,有人歡樂有人憂愁,有人驚喜有人失落欣孤,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,523評(píng)論 28 53
  • 信任包括信任自己和信任他人 很多時(shí)候馋没,很多事情,失敗降传、遺憾篷朵、錯(cuò)過,源于不自信婆排,不信任他人 覺得自己做不成声旺,別人做不...
    吳氵晃閱讀 6,181評(píng)論 4 8
  • 步驟:發(fā)微博01-導(dǎo)航欄內(nèi)容 -> 發(fā)微博02-自定義TextView -> 發(fā)微博03-完善TextView和...
    dibadalu閱讀 3,127評(píng)論 1 3