后端:MyBatis緩存知識(shí)介紹,你學(xué)到了嗎?
今天給大家分享一下MyBatis緩存知識(shí)介紹,希望對(duì)大家日常的開發(fā)當(dāng)中能有所幫助!
一、MyBatis一級(jí)緩存
1、一級(jí)緩存介紹
當(dāng)我們的程序MyBatis開啟一次和數(shù)據(jù)庫(kù)的會(huì)話,MyBatis會(huì)自動(dòng)創(chuàng)建出一個(gè)SqlSession對(duì)象表示這一次數(shù)據(jù)庫(kù)的會(huì)話。在同一個(gè)數(shù)據(jù)庫(kù)會(huì)話當(dāng)中,MyBatis提供了一級(jí)緩存的方案優(yōu)化這部分場(chǎng)景,針對(duì)相同的SQL查詢語(yǔ)句,會(huì)優(yōu)先命中一級(jí)緩存,避免再次對(duì)數(shù)據(jù)庫(kù)進(jìn)行查詢,從而提高查詢性能、減輕數(shù)據(jù)庫(kù)的壓力。
開啟一級(jí)緩存
MyBatis的配置文件加上如下:
- <setting name="localCacheScope" value="SESSION"/>
注意:localCacheScope 值有兩個(gè) SESSION(開啟一級(jí)緩存)/Statement(關(guān)閉一級(jí)緩存)
一級(jí)緩存失效場(chǎng)景
- SqlSeesion實(shí)例不同
- SqlSeesion實(shí)例相同,查詢條件不同
- SqlSeesion對(duì)象相同,查詢條件也相同,但兩次查詢之間執(zhí)行了增刪改操作
- SqlSeesion對(duì)象相同,兩次查詢條件相同,中間無其它增刪改操作,但使用了clearCache()方法
總結(jié)
- MyBatis一級(jí)緩存的生命周期和SqlSession一致。默認(rèn)是開啟狀態(tài)。
- MyBatis一級(jí)緩存采用HashMap性能較差
- 分布式環(huán)境下對(duì)數(shù)據(jù)庫(kù)操作容易引起臟數(shù)據(jù),不推薦開啟MyBatis一級(jí)緩存
二、MyBatis二級(jí)緩存
1、二級(jí)緩存介紹
MyBatis一級(jí)緩存生命周期是一個(gè)SqlSession內(nèi)部,如果多個(gè) SqlSession 需要共享緩存,則需要開啟二級(jí)緩存,開啟二級(jí)緩存后,會(huì)使用 CachingExecutor 裝飾 Executor,進(jìn)入一級(jí)緩存的查詢流程前,先在CachingExecutor 進(jìn)行二級(jí)緩存的查詢。
2、為什么有二級(jí)緩存?
- 為了避免和數(shù)據(jù)庫(kù)頻繁交互。這是設(shè)計(jì)緩存的主要原因。
- 當(dāng)Spring和MyBatis整合時(shí),每次查詢之后都要進(jìn)行關(guān)閉sqlsession,關(guān)閉之后數(shù)據(jù)被清空。所以MyBatis和Spring整合之后,一級(jí)緩存是沒有意義的。如果開啟二級(jí)緩存,關(guān)閉sqlsession后,會(huì)把該sqlsession一級(jí)緩存中的數(shù)據(jù)添加到mapper namespace的二級(jí)緩存中。這樣,緩存在sqlsession關(guān)閉之后依然存在。
當(dāng)開啟二級(jí)緩存數(shù)據(jù)庫(kù)查詢流程先后順序?yàn)椋憾?jí)緩存 -> 一級(jí)緩存 -> 數(shù)據(jù)庫(kù)
3、如何開啟二級(jí)緩存
二級(jí)緩存默認(rèn)是不開啟的,需要手動(dòng)開啟二級(jí)緩存,MyBatis的配置文件加上如下:
- <settings>
- <setting name = "cacheEnabled" value = "true" />
- </settings>
然后在還需要在 Mapper 的xml 配置文件中加入
cache屬性介紹
eviction:設(shè)置回收策略,默認(rèn)是LRU策略。
- LRU - 最近最少回收,移除最長(zhǎng)時(shí)間不被使用的對(duì)象
- FIFO - 先進(jìn)先出,按照緩存進(jìn)入的順序來移除它們
- SOFT - 軟引用,移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對(duì)象
- WEAK - 弱引用,更積極的移除基于垃圾收集器和弱引用規(guī)則的對(duì)象
flushinterval:緩存刷新間隔,緩存多長(zhǎng)時(shí)間刷新一次,默認(rèn)不清空,設(shè)置一個(gè)毫秒值
readOnly: 是否只讀;true 只讀,MyBatis 認(rèn)為所有從緩存中獲取數(shù)據(jù)的操作都是只讀操作,不會(huì)修改數(shù)據(jù)。MyBatis 為了加快獲取數(shù)據(jù),直接就會(huì)將數(shù)據(jù)在緩存中的引用交給用戶。不安全,速度快。讀寫(默認(rèn)):MyBatis 覺得數(shù)據(jù)可能會(huì)被修改
size : 緩存可存放多少個(gè)元素
type: 指定自定義緩存的全類名(實(shí)現(xiàn)Cache 接口即可)
blocking:若緩存中找不到對(duì)應(yīng)的key,是否會(huì)一直blocking,直到有對(duì)應(yīng)的數(shù)據(jù)進(jìn)入緩存。
注意:
- 在事務(wù)提交之前,并不會(huì)真正存儲(chǔ)到二級(jí)緩存,而是先存儲(chǔ)到一個(gè)臨時(shí)屬性,等事務(wù)提交之后才會(huì)真正存儲(chǔ)到二級(jí)緩存。因此需要commit事務(wù)之后才能生效。
- 如果使用的是MyBatis默認(rèn)緩存,結(jié)果集對(duì)象需要實(shí)現(xiàn)序列化接口(Serializable),否則會(huì)報(bào)錯(cuò)。
4、二級(jí)緩存適用場(chǎng)景
- 適合頻繁訪問且用戶對(duì)查詢結(jié)果實(shí)時(shí)性要求不是很高的查詢,
這時(shí)采用二級(jí)緩存可降低數(shù)據(jù)庫(kù)訪問量,提高數(shù)據(jù)庫(kù)的性能,例如:查詢耗時(shí)較高的統(tǒng)計(jì)報(bào)表SQL、按固定時(shí)間維度查詢的SQL(每月的訂單信息等等)。
- 適合查詢多寫入少的場(chǎng)景開啟。
因?yàn)槿魏螌?duì)數(shù)據(jù)庫(kù)的(insert、update、delete)操作都會(huì)觸發(fā)緩存的更新,從而造成緩存失效。
5、二級(jí)緩存失效場(chǎng)景
- 第一次SqlSession 未提交
- 對(duì)數(shù)據(jù)庫(kù)對(duì)應(yīng)的數(shù)據(jù)表執(zhí)行了的(insert、update、delete)操作
6、總結(jié)
mybatis二級(jí)緩存針對(duì)大多數(shù)的業(yè)務(wù)系統(tǒng)都不推薦使用,因?yàn)闃I(yè)務(wù)系統(tǒng)數(shù)據(jù)操作比較頻繁、自帶的二級(jí)緩存性能也不是很高。二級(jí)緩存很難起到實(shí)際的作用??梢砸玫谌骄彺妗?/p>
個(gè)人博客網(wǎng)站:https://programmerblog.xyz
本文轉(zhuǎn)載自微信公眾號(hào)「IT技術(shù)分享社區(qū)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系IT技術(shù)分享社區(qū)公眾號(hào)。