mybatis分為一級緩存和二級緩存,在默認(rèn)的情況下暂刘,Mybatis只會開啟一級緩存
一級緩存
一級緩存是一次會話(SqlSession)的緩存,相當(dāng)于本地緩存
對于同一個(gè)SqlSession對象逼裆,在參數(shù)和SQL完成一樣的情況下蓝仲,如果緩存沒有過期,只執(zhí)行一次SQL語句
一級緩存的生命周期:
開啟一個(gè)新的會話時(shí)會創(chuàng)建一個(gè)新的SqlSession對象泡态,里面會存在一個(gè)新的Excutor對象搂漠,Excutor對象持有一個(gè)新的PerpetualCache對象,會話結(jié)束時(shí)某弦,Excutor對象和PerpetualCache對象一起釋放掉
SqlSession調(diào)用close方法后會清掉PerpetualCache桐汤,一級緩存就不可用了
調(diào)用clearCache而克,會清空PerpetualCache對象,但是可用
該SqlSession中執(zhí)行insert怔毛,delete员萍,update語句后會清除掉PerpetualCache中的數(shù)據(jù)
完全相同的查詢:
傳入的statementId(接口的形式就是方法名)
查詢時(shí)的結(jié)果集中的結(jié)果范圍
這次查詢所產(chǎn)生的最終要傳遞給JDBC java.sql.Preparedstatement的Sql語句字符串(boundSql.getSql()沒有參數(shù))
傳遞給java.sql.Statement要設(shè)置的參數(shù)值
二級緩存
Mybatis的二級緩存是全局緩存,他可以提高對數(shù)據(jù)庫的查詢效率拣度,提高應(yīng)用的性能
默認(rèn)是不開啟的碎绎,如果要開啟,Mybatis要求返回的POJO是可序列化的抗果,如果配置了二級緩存筋帖,就意味著:
- 映射語句文件中的所有select語句將會被緩存。
- 映射語句文件中的所欲insert冤馏、update和delete語句會刷新緩存幕随。
- 緩存會使用默認(rèn)的Least Recently Used(LRU,最近最少使用的)算法來收回宿接。
- 根據(jù)時(shí)間表赘淮,比如No Flush Interval,(CNFI沒有刷新間隔),緩存不會以任何時(shí)間順序來刷新睦霎。
- 緩存會存儲列表集合或?qū)ο?無論查詢方法返回什么)的1024個(gè)引用
- 緩存會被視為是read/write(可讀/可寫)的緩存梢卸,意味著對象檢索不是共享的,而且可以安全的被調(diào)用者修改副女,不干擾其他調(diào)用者或線程所做的潛在修改蛤高。
二級緩存開啟的方式:
-
在xml映射文件中聲明
<!--開啟本mapper的namespace下的二級緩存--> <!-- eviction:代表的是緩存回收策略,目前MyBatis提供以下策略碑幅。 (1) LRU,最近最少使用的戴陡,一處最長時(shí)間不用的對象 (2) FIFO,先進(jìn)先出,按對象進(jìn)入緩存的順序來移除他們 (3) SOFT,軟引用沟涨,移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對象 (4) WEAK,弱引用恤批,更積極的移除基于垃圾收集器狀態(tài)和弱引用規(guī)則的對象。這里采用的是LRU裹赴, 移除最長時(shí)間不用的對形象 flushInterval:刷新間隔時(shí)間喜庞,單位為毫秒,這里配置的是100秒刷新棋返,如果你不配置它延都,那么當(dāng) SQL被執(zhí)行的時(shí)候才會去刷新緩存。 size:引用數(shù)目睛竣,一個(gè)正整數(shù)晰房,代表緩存最多可以存儲多少個(gè)對象,不宜設(shè)置過大。設(shè)置過大會導(dǎo)致內(nèi)存溢出殊者。 這里配置的是1024個(gè)對象 readOnly:只讀与境,意味著緩存數(shù)據(jù)只能讀取而不能修改,這樣設(shè)置的好處是我們可以快速讀取緩存幽污,缺點(diǎn)是我們沒有辦法修改緩存,他的默認(rèn)值是false簿姨,不允許我們修改 type:指定自定義緩存的全限定名(需要實(shí)現(xiàn)Cache接口) blocking:若緩存中找不到對應(yīng)的key距误,是否會一直blocking,直到有對應(yīng)的數(shù)據(jù)進(jìn)入緩存 --> <cache eviction="LRU" flushInterval="100000" readOnly="true" size="1024"/> <!--可以通過設(shè)置useCache來規(guī)定這個(gè)sql是否開啟緩存扁位,ture是開啟准潭,false是關(guān)閉--> <select id="selectAllStudents" resultMap="studentMap" useCache="true"> SELECT id, name, age FROM student </select> <!--刷新二級緩存 <select id="selectAllStudents" resultMap="studentMap" flushCache="true"> SELECT id, name, age FROM student </select> -->
在配置文件中開啟
```xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--這個(gè)配置使全局的映射器(二級緩存)啟用或禁用緩存-->
<setting name="cacheEnabled" value="true" />
.....
</settings>
....
</configuration>
當(dāng)二級緩存開啟后,同一個(gè)命名空間(namespace) 所有的操作語句域仇,都影響著一個(gè)共同的 cache刑然,也就是二級緩存被多個(gè) SqlSession 共享,是一個(gè)全局的變量暇务。當(dāng)開啟緩存后泼掠,數(shù)據(jù)的查詢執(zhí)行的流程就是 二級緩存 -> 一級緩存 -> 數(shù)據(jù)庫。
參考:
https://www.cnblogs.com/happyflyingpig/p/7739749.html
https://blog.csdn.net/weixin_37139197/article/details/82908377