mybatis分為一級緩存和二級緩存,在默認的情況下,Mybatis只會開啟一級緩存
一級緩存
一級緩存是一次會話(SqlSession)的緩存,相當(dāng)于本地緩存
對于同一個SqlSession對象,在參數(shù)和SQL完成一樣的情況下,如果緩存沒有過期,只執(zhí)行一次SQL語句
一級緩存的生命周期:
開啟一個新的會話時會創(chuàng)建一個新的SqlSession對象,里面會存在一個新的Excutor對象,Excutor對象持有一個新的PerpetualCache對象,會話結(jié)束時,Excutor對象和PerpetualCache對象一起釋放掉
SqlSession調(diào)用close方法后會清掉PerpetualCache,一級緩存就不可用了
調(diào)用clearCache,會清空PerpetualCache對象,但是可用
該SqlSession中執(zhí)行insert,delete,update語句后會清除掉PerpetualCache中的數(shù)據(jù)
完全相同的查詢:
傳入的statementId(接口的形式就是方法名)
查詢時的結(jié)果集中的結(jié)果范圍
這次查詢所產(chǎn)生的最終要傳遞給JDBC java.sql.Preparedstatement的Sql語句字符串(boundSql.getSql()沒有參數(shù))
傳遞給java.sql.Statement要設(shè)置的參數(shù)值
二級緩存
Mybatis的二級緩存是全局緩存,他可以提高對數(shù)據(jù)庫的查詢效率,提高應(yīng)用的性能
默認是不開啟的,如果要開啟,Mybatis要求返回的POJO是可序列化的,如果配置了二級緩存,就意味著:
- 映射語句文件中的所有select語句將會被緩存。
- 映射語句文件中的所欲insert、update和delete語句會刷新緩存。
- 緩存會使用默認的Least Recently Used(LRU,最近最少使用的)算法來收回。
- 根據(jù)時間表,比如No Flush Interval,(CNFI沒有刷新間隔),緩存不會以任何時間順序來刷新。
- 緩存會存儲列表集合或?qū)ο?無論查詢方法返回什么)的1024個引用
- 緩存會被視為是read/write(可讀/可寫)的緩存,意味著對象檢索不是共享的,而且可以安全的被調(diào)用者修改,不干擾其他調(diào)用者或線程所做的潛在修改。
二級緩存開啟的方式:
-
在xml映射文件中聲明
<!--開啟本mapper的namespace下的二級緩存--> <!-- eviction:代表的是緩存回收策略,目前MyBatis提供以下策略。 (1) LRU,最近最少使用的,一處最長時間不用的對象 (2) FIFO,先進先出,按對象進入緩存的順序來移除他們 (3) SOFT,軟引用,移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對象 (4) WEAK,弱引用,更積極的移除基于垃圾收集器狀態(tài)和弱引用規(guī)則的對象。這里采用的是LRU, 移除最長時間不用的對形象 flushInterval:刷新間隔時間,單位為毫秒,這里配置的是100秒刷新,如果你不配置它,那么當(dāng) SQL被執(zhí)行的時候才會去刷新緩存。 size:引用數(shù)目,一個正整數(shù),代表緩存最多可以存儲多少個對象,不宜設(shè)置過大。設(shè)置過大會導(dǎo)致內(nèi)存溢出。 這里配置的是1024個對象 readOnly:只讀,意味著緩存數(shù)據(jù)只能讀取而不能修改,這樣設(shè)置的好處是我們可以快速讀取緩存,缺點是我們沒有辦法修改緩存,他的默認值是false,不允許我們修改 type:指定自定義緩存的全限定名(需要實現(xiàn)Cache接口) blocking:若緩存中找不到對應(yīng)的key,是否會一直blocking,直到有對應(yīng)的數(shù)據(jù)進入緩存 --> <cache eviction="LRU" flushInterval="100000" readOnly="true" size="1024"/> <!--可以通過設(shè)置useCache來規(guī)定這個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>
<!--這個配置使全局的映射器(二級緩存)啟用或禁用緩存-->
<setting name="cacheEnabled" value="true" />
.....
</settings>
....
</configuration>
當(dāng)二級緩存開啟后,同一個命名空間(namespace) 所有的操作語句,都影響著一個共同的 cache,也就是二級緩存被多個 SqlSession 共享,是一個全局的變量。當(dāng)開啟緩存后,數(shù)據(jù)的查詢執(zhí)行的流程就是 二級緩存 -> 一級緩存 -> 數(shù)據(jù)庫。
參考:
https://www.cnblogs.com/happyflyingpig/p/7739749.html
https://blog.csdn.net/weixin_37139197/article/details/82908377