緩存機(jī)制減輕數(shù)據(jù)庫壓力,提高數(shù)據(jù)庫性能
mybatis的緩存分為兩級:一級緩存、二級緩存
一級緩存為 ?SqlSession
? 緩存,緩存的數(shù)據(jù)只在 SqlSession 內(nèi)有效。在操作數(shù)據(jù)庫的時候需要先創(chuàng)建 SqlSession 會話對象,在對象中有一個 HashMap 用于存儲緩存數(shù)據(jù),此 HashMap 是當(dāng)前會話對象私有的,別的 SqlSession 會話對象無法訪問。
具體流程:
第一次執(zhí)行 select 完畢會將查到的數(shù)據(jù)寫入 SqlSession 內(nèi)的 HashMap 中緩存起來
第二次執(zhí)行 select 會從緩存中查數(shù)據(jù),如果 select 同傳參數(shù)一樣,那么就能從緩存中返回數(shù)據(jù),不用去數(shù)據(jù)庫了,從而提高了效率
注意:
1、如果 SqlSession 執(zhí)行了 DML 操作(insert、update、delete),并 commit 了,那么 mybatis 就會清空當(dāng)前 SqlSession 緩存中的所有緩存數(shù)據(jù),這樣可以保證緩存中的存的數(shù)據(jù)永遠(yuǎn)和數(shù)據(jù)庫中一致,避免出現(xiàn)差異
2、當(dāng)一個 SqlSession 結(jié)束后那么他里面的一級緩存也就不存在了, mybatis 默認(rèn)是開啟一級緩存,不需要配置
3、 mybatis 的緩存是基于 [namespace:sql語句:參數(shù)] 來進(jìn)行緩存的,意思就是, SqlSession 的 HashMap 存儲緩存數(shù)據(jù)時,是使用 [namespace:sql:參數(shù)] 作為 key ,查詢返回的語句作為 value 保存的
二級緩存是? mapper
? 級別的緩存,也就是同一個 namespace 的 mapper.xml ,當(dāng)多個 SqlSession 使用同一個 Mapper 操作數(shù)據(jù)庫的時候,得到的數(shù)據(jù)會緩存在同一個二級緩存區(qū)域
二級緩存默認(rèn)是沒有開啟的。需要在 setting 全局參數(shù)中配置開啟二級緩存
開啟二級緩存步驟:
1、?conf.xml
? 配置全局變量開啟二級緩存
<settings>
<setting name="cacheEnabled" value="true"/>默認(rèn)是false:關(guān)閉二級緩存
<settings>
2、在? userMapper.xml
?中配置
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>當(dāng)前mapper下所有語句開啟二級緩存
這里配置了一個 ?FIFO
?緩存,并每隔60秒刷新,最大存儲512個對象,而返回的對象是只讀的,因此在不同線程中的調(diào)用者之間修改它們會導(dǎo)致沖突??捎玫氖栈夭呗杂校J(rèn)的是?LRU
?:
LRU
?- 最近最少使用的;移除最長時間不被使用的對象。 FIFO
?- 先進(jìn)先出;按對象進(jìn)入緩存的順序來移除它們。 SOFT
?- 軟引用;移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對象 WEAK
?- 弱引用;更積極地移除基干垃圾收集器狀態(tài)和弱引用規(guī)則的對象若想禁用當(dāng)前?select
?語句的二級緩存,添加 ?useCache="false"
?修改如下:
<select id="getCountByName" parameterType="java.util.Map" resultType="INTEGER" statementType="CALLABLE" useCache="false">
具體流程:
1.當(dāng)一個? sqlseesion
?執(zhí)行了一次? select
? 后,在關(guān)閉此? session
? 的時候,會將查詢結(jié)果緩存到二級緩存
2.當(dāng)另一個? sqlsession
?執(zhí)行? select
? 時,首先會在他自己的一級緩存中找,如果沒找到,就回去二級緩存中找,找到了就返回,就不用去數(shù)據(jù)庫了,從而減少了數(shù)據(jù)庫壓力提高了性能
注意:
1、如果 ?SqlSession
? 執(zhí)行了 DML 操作?(insert、update、delete)
?,并 ?commit
? 了,那么 ?mybatis
? 就會清空當(dāng)前? mapper
? 緩存中的所有緩存數(shù)據(jù),這樣可以保證緩存中的存的數(shù)據(jù)永遠(yuǎn)和數(shù)據(jù)庫中一致,避免出現(xiàn)差異
2、? mybatis
? 的一級緩存是基于? [namespace:sql語句:參數(shù)]
?來進(jìn)行緩存的,意思就是,?SqlSession
? 的 ?HashMap
? 存儲緩存數(shù)據(jù)時,是使用 ?[namespace:sql:參數(shù)]
?作為 ?key
? ,查詢返回的語句作為 ?value
? 保存的。
更多建議: