MyBatis緩存機(jī)制

2022-07-22 11:24 更新

緩存機(jī)制減輕數(shù)據(jù)庫(kù)壓力,提高數(shù)據(jù)庫(kù)性能

mybatis的緩存分為兩級(jí):一級(jí)緩存、二級(jí)緩存

一級(jí)緩存:

一級(jí)緩存為 ?SqlSession? 緩存,緩存的數(shù)據(jù)只在 SqlSession 內(nèi)有效。在操作數(shù)據(jù)庫(kù)的時(shí)候需要先創(chuàng)建 SqlSession 會(huì)話對(duì)象,在對(duì)象中有一個(gè) HashMap 用于存儲(chǔ)緩存數(shù)據(jù),此 HashMap 是當(dāng)前會(huì)話對(duì)象私有的,別的 SqlSession 會(huì)話對(duì)象無(wú)法訪問(wèn)。

具體流程:

第一次執(zhí)行 select 完畢會(huì)將查到的數(shù)據(jù)寫入 SqlSession 內(nèi)的 HashMap 中緩存起來(lái)

第二次執(zhí)行 select 會(huì)從緩存中查數(shù)據(jù),如果 select 同傳參數(shù)一樣,那么就能從緩存中返回?cái)?shù)據(jù),不用去數(shù)據(jù)庫(kù)了,從而提高了效率

注意:

1、如果 SqlSession 執(zhí)行了 DML 操作(insert、update、delete),并 commit 了,那么 mybatis 就會(huì)清空當(dāng)前 SqlSession 緩存中的所有緩存數(shù)據(jù),這樣可以保證緩存中的存的數(shù)據(jù)永遠(yuǎn)和數(shù)據(jù)庫(kù)中一致,避免出現(xiàn)差異

2、當(dāng)一個(gè) SqlSession 結(jié)束后那么他里面的一級(jí)緩存也就不存在了, mybatis 默認(rèn)是開啟一級(jí)緩存,不需要配置

3、 mybatis 的緩存是基于 [namespace:sql語(yǔ)句:參數(shù)] 來(lái)進(jìn)行緩存的,意思就是, SqlSession 的 HashMap 存儲(chǔ)緩存數(shù)據(jù)時(shí),是使用 [namespace:sql:參數(shù)] 作為 key ,查詢返回的語(yǔ)句作為 value 保存的

二級(jí)緩存:

二級(jí)緩存是? mapper? 級(jí)別的緩存,也就是同一個(gè) namespace 的 mapper.xml ,當(dāng)多個(gè) SqlSession 使用同一個(gè) Mapper 操作數(shù)據(jù)庫(kù)的時(shí)候,得到的數(shù)據(jù)會(huì)緩存在同一個(gè)二級(jí)緩存區(qū)域

二級(jí)緩存默認(rèn)是沒有開啟的。需要在 setting 全局參數(shù)中配置開啟二級(jí)緩存

開啟二級(jí)緩存步驟:

1、?conf.xml? 配置全局變量開啟二級(jí)緩存

<settings>
<setting name="cacheEnabled" value="true"/>默認(rèn)是false:關(guān)閉二級(jí)緩存
<settings>

2、在? userMapper.xml ?中配置

<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>當(dāng)前mapper下所有語(yǔ)句開啟二級(jí)緩存

這里配置了一個(gè) ?FIFO ?緩存,并每隔60秒刷新,最大存儲(chǔ)512個(gè)對(duì)象,而返回的對(duì)象是只讀的,因此在不同線程中的調(diào)用者之間修改它們會(huì)導(dǎo)致沖突??捎玫氖栈夭呗杂校J(rèn)的是?LRU?:

  1. ?LRU ?- 最近最少使用的;移除最長(zhǎng)時(shí)間不被使用的對(duì)象。 
  2. ?FIFO ?- 先進(jìn)先出;按對(duì)象進(jìn)入緩存的順序來(lái)移除它們。 
  3. ?SOFT?- 軟引用;移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對(duì)象 
  4. ?WEAK ?- 弱引用;更積極地移除基干垃圾收集器狀態(tài)和弱引用規(guī)則的對(duì)象

若想禁用當(dāng)前?select?語(yǔ)句的二級(jí)緩存,添加 ?useCache="false"?修改如下:

<select id="getCountByName" parameterType="java.util.Map" resultType="INTEGER" statementType="CALLABLE" useCache="false">

具體流程:

1.當(dāng)一個(gè)? sqlseesion ?執(zhí)行了一次? select? 后,在關(guān)閉此? session? 的時(shí)候,會(huì)將查詢結(jié)果緩存到二級(jí)緩存

2.當(dāng)另一個(gè)? sqlsession ?執(zhí)行? select? 時(shí),首先會(huì)在他自己的一級(jí)緩存中找,如果沒找到,就回去二級(jí)緩存中找,找到了就返回,就不用去數(shù)據(jù)庫(kù)了,從而減少了數(shù)據(jù)庫(kù)壓力提高了性能

注意:

1、如果 ?SqlSession? 執(zhí)行了 DML 操作?(insert、update、delete)?,并 ?commit? 了,那么 ?mybatis? 就會(huì)清空當(dāng)前? mapper? 緩存中的所有緩存數(shù)據(jù),這樣可以保證緩存中的存的數(shù)據(jù)永遠(yuǎn)和數(shù)據(jù)庫(kù)中一致,避免出現(xiàn)差異

2、? mybatis? 的一級(jí)緩存是基于? [namespace:sql語(yǔ)句:參數(shù)] ?來(lái)進(jìn)行緩存的,意思就是,?SqlSession? 的 ?HashMap? 存儲(chǔ)緩存數(shù)據(jù)時(shí),是使用 ?[namespace:sql:參數(shù)] ?作為 ?key? ,查詢返回的語(yǔ)句作為 ?value? 保存的。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)