mybatis中的查询缓存
轉(zhuǎn)載自:https://www.cnblogs.com/zhangzongle/p/6211285.html
查詢緩存
Mybatis提供查詢緩存,用于減輕數(shù)據(jù)壓力,提高數(shù)據(jù)庫壓力。
Mybatis提供一級(jí)緩存和二級(jí)緩存。
在操作數(shù)據(jù)庫時(shí)需要構(gòu)造SqlSession對(duì)象,在對(duì)象中有一個(gè)數(shù)據(jù)結(jié)構(gòu)(HashMap)用于緩存數(shù)據(jù)。
不同的SqlSession之間的緩存數(shù)據(jù)區(qū)域是互相不影響的。
Mybatis一級(jí)緩存的作用域是同一個(gè)SqlSession,在同一個(gè)sqlSession中兩次執(zhí)行相同的sql語句,第一次執(zhí)行完畢會(huì)將數(shù)據(jù)庫中查詢的數(shù)據(jù)寫到緩存(內(nèi)存),第二次會(huì)從緩存中獲取數(shù)據(jù)將不再從數(shù)據(jù)庫查詢,從而提高查詢效率。當(dāng)一個(gè)sqlSession結(jié)束后該sqlSession中的一級(jí)緩存也就不存在了。Mybatis默認(rèn)開啟一級(jí)緩存。
Mybatis二級(jí)緩存是多個(gè)SqlSession共享的,其作用域是mapper的同一個(gè)namespace,不同的sqlSession兩次執(zhí)行相同namespace下的sql語句且向sql中傳遞參數(shù)也相同即最終執(zhí)行相同的sql語句,第一次執(zhí)行完畢會(huì)將數(shù)據(jù)庫中查詢的數(shù)據(jù)寫到緩存(內(nèi)存),第二次會(huì)從緩存中獲取數(shù)據(jù)將不再從數(shù)據(jù)庫查詢,從而提高查詢效率。Mybatis默認(rèn)沒有開啟二級(jí)緩存需要在setting全局參數(shù)中配置開啟二級(jí)緩存。
1、一級(jí)緩存
第一次發(fā)起查詢,先去找緩存中是否有id為1的用戶信息,如果沒有,從數(shù)據(jù)庫中查詢用戶信息。
得到用戶信息,將用戶信息存儲(chǔ)到一級(jí)緩存中。
第二次發(fā)起查詢用戶id為1的用戶信息,先去緩存中是否有id為1的用戶信息,緩存中有,直接從緩存中獲取用戶信息。
如果SqlSession去執(zhí)行commit操作(執(zhí)行插入、更新、刪除),清空SqlSession中的一級(jí)緩存。目的是為了讓緩存中存儲(chǔ)的是最新的信息,避免臟讀。
Mybatis默認(rèn)支持一級(jí)緩存,不需要在配置文件中配置。
Mybatis內(nèi)部存儲(chǔ)緩存使用一個(gè)HashMap,key為hashCode+sqlId+Sql語句。value為從查詢出來映射生成的java對(duì)象。
應(yīng)用場(chǎng)景:
2、二級(jí)緩存
SqlSession1去查詢用戶id為1的用戶信息,查詢到用戶信息會(huì)將查詢數(shù)據(jù)存儲(chǔ)到二級(jí)緩存中。
SqlSession2去查詢用戶id為1的用戶信息,去緩存中找是否存在數(shù)據(jù),如果存在直接從緩存中取出數(shù)據(jù)。
二級(jí)緩存區(qū)域是根據(jù)mapper的namespace劃分的,相同namespace的mapper查詢數(shù)據(jù)放在同一個(gè)區(qū)域,如果使用mapper代理方法每個(gè)mapper的namespace都不同,此時(shí)可以理解為二級(jí)緩存區(qū)域是根據(jù)mapper劃分。
每次查詢會(huì)先從緩存區(qū)域找,如果找不到從數(shù)據(jù)庫查詢,查詢到數(shù)據(jù)將數(shù)據(jù)寫入緩存。
Mybatis內(nèi)部存儲(chǔ)緩存使用一個(gè)HashMap,key為hashCode+sqlId+Sql語句。value為從查詢出來映射生成的java對(duì)象
sqlSession執(zhí)行insert、update、delete等操作commit提交后會(huì)清空緩存區(qū)域。
開啟二級(jí)緩存:
1、在核心配置文件mybatis-config.xml中加入
<setting name="cacheEnabled" value="true"/>2、 要在你的Mapper映射文件中添加一行: <cache /> ,表示此mapper開啟二級(jí)緩存。
3、二級(jí)緩存需要查詢結(jié)果映射的pojo對(duì)象實(shí)現(xiàn)java.io.Serializable接口實(shí)現(xiàn)序列化和反序列化操作,注意如果存在父類、成員pojo都需要實(shí)現(xiàn)序列化接口。
為了將緩存數(shù)據(jù)取出執(zhí)行反序列化,因?yàn)槎?jí)緩存存儲(chǔ)介質(zhì)多種多樣,不一定在內(nèi)存。
禁用二級(jí)緩存:
在statement中設(shè)置useCache=false可以禁用當(dāng)前select語句的二級(jí)緩存,即每次查詢都會(huì)發(fā)出sql去查詢,默認(rèn)情況是true,即該sql使用二級(jí)緩存。
<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">刷新緩存(就是清空緩存):
設(shè)置statement配置中的flushCache=”true” 屬性,默認(rèn)情況下為true即刷新緩存,如果改成false則不會(huì)刷新。使用緩存時(shí)如果手動(dòng)修改數(shù)據(jù)庫表中的查詢數(shù)據(jù)會(huì)出現(xiàn)臟讀。
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">應(yīng)用場(chǎng)景:
對(duì)于訪問多的查詢請(qǐng)求且用戶對(duì)查詢結(jié)果實(shí)時(shí)性要求不高,此時(shí)可采用mybatis二級(jí)緩存技術(shù)降低數(shù)據(jù)庫訪問量,提高訪問速度,業(yè)務(wù)場(chǎng)景比如:耗時(shí)較高的統(tǒng)計(jì)分析sql、電話賬單查詢sql等。
實(shí)現(xiàn)方法如下:通過設(shè)置刷新間隔時(shí)間,由mybatis每隔一段時(shí)間自動(dòng)清空緩存,根據(jù)數(shù)據(jù)變化頻率設(shè)置緩存刷新間隔flushInterval,比如設(shè)置為30分鐘、60分鐘、24小時(shí)等,根據(jù)需求而定。局限性:
mybatis二級(jí)緩存對(duì)細(xì)粒度的數(shù)據(jù)級(jí)別的緩存實(shí)現(xiàn)不好,比如如下需求:對(duì)商品信息進(jìn)行緩存,由于商品信息查詢?cè)L問量大,但是要求用戶每次都能查詢最新的商品信息,此時(shí)如果使用mybatis的二級(jí)緩存就無法實(shí)現(xiàn)當(dāng)一個(gè)商品變化時(shí)只刷新該商品的緩存信息而不刷新其它商品的信息,因?yàn)閙ybaits的二級(jí)緩存區(qū)域以mapper為單位劃分,當(dāng)一個(gè)商品信息變化會(huì)將所有商品信息的緩存數(shù)據(jù)全部清空。解決此類問題需要在業(yè)務(wù)層根據(jù)需求對(duì)數(shù)據(jù)有針對(duì)性緩存。
總結(jié)
以上是生活随笔為你收集整理的mybatis中的查询缓存的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle数据库IMP-00010错误
- 下一篇: ORA-01756: quoted st