mybatis提供了緩存機制減輕數據庫壓力,提升數據庫性能
mybatis的緩存分爲兩級:一級緩存、二級緩存
一級緩存是SqlSession級別的緩存,緩存的數據只在SqlSession內有效
二級緩存是mapper級別的緩存,同一個namespace公用這一個緩存,因此對SqlSession是共享的
一級緩存:
mybatis的一級緩存是SqlSession級別的緩存,在操做數據庫的時候須要先建立SqlSession會話對象,在對象中有一個HashMap用於存儲緩存數據,此HashMap是當前會話對象私有的,別的SqlSession會話對象沒法訪問。
具體流程:
1.第一次執行select完畢會將查到的數據寫入SqlSession內的HashMap中緩存起來
2.第二次執行select會從緩存中查數據,若是select相同且傳參數同樣,那麼就能從緩存中返回數據,不用去數據庫了,從而提升了效率
注意事項:
1.若是SqlSession執行了DML操做(insert、update、delete),並commit了,那麼mybatis就會清空當前SqlSession緩存中的全部緩存數據,這樣能夠保證緩存中的存的數據永遠和數據庫中一致,避免出現髒讀
2.當一個SqlSession結束後那麼他裏面的一級緩存也就不存在了,mybatis默認是開啓一級緩存,不須要配置
3.mybatis的緩存是基於[namespace:sql語句:參數]來進行緩存的,意思就是,SqlSession的HashMap存儲緩存數據時,是使用[namespace:sql:參數]做爲key,查詢返回的語句做爲value保存的。
二級緩存:
二級緩存是mapper級別的緩存,也就是同一個namespace的mapper.xml,當多個SqlSession使用同一個Mapper操做數據庫的時候,獲得的數據會緩存在同一個二級緩存區域
二級緩存默認是沒有開啓的。須要在setting全局參數中配置開啓二級緩存
mybatis-config.xml:
<setting name="cacheEnabled" value="true"/>
默認是 false:關閉
在userMapper.xml中配置:
<cache />當前mapper下全部語句開啓二級緩存
若想禁用當前select語句的二級緩存,添加useCache="false"修改以下:
<select id="getCountByName" parameterType="java.util.Map" resultType="INTEGER" statementType="CALLABLE" useCache="false">
具體流程:
1.當一個sqlseesion執行了一次select後,在關閉此session的時候,會將查詢結果緩存到二級緩存
2.當另外一個sqlsession執行select時,首先會在他本身的一級緩存中找,若是沒找到,就回去二級緩存中找,找到了就返回,就不用去數據庫了,從而減小了數據庫壓力提升了性能
注意事項:
1.若是SqlSession執行了DML操做(insert、update、delete),並commit了,那麼mybatis就會清空當前mapper緩存中的全部緩存數據,這樣能夠保證緩存中的存的數據永遠和數據庫中一致,避免出現髒讀
2.mybatis的緩存是基於[namespace:sql語句:參數]來進行緩存的,意思就是,SqlSession的HashMap存儲緩存數據時,是使用[namespace:sql:參數]做爲key,查詢返回的語句做爲value保存的。
3.實體類對象必需要實現序列化接口
查找規則:
一、先判斷二級緩存是否開啓,若是沒開啓,再判斷一級緩存是否開啓,若是沒開啓,直接查數據庫
二、若是一級緩存關閉,即便二級緩存開啓也沒有數據,由於二級緩存的數據從一級緩存獲取
三、通常不會關閉一級緩存
四、二級緩存默認不開啓
五、若是二級緩存關閉,直接判斷一級緩存是否有數據,若是沒有就查數據庫
六、若是二級緩存開啓,先判斷二級緩存有沒有數據,若是有就直接返回;若是沒有,就查詢一級緩存,若是有就返回,沒有就查詢數據庫;
/*一級緩存(sqlsession級別的緩存,默認開啓):
* 同一個sqlsession執行相同的sql語句,第二次直接從緩存獲取
* 二級緩存(mapper基本的緩存,默認關閉,基本上不用,實際中也不怎麼用):
* 不一樣的sqlsession執行一樣的sql語句也會緩存
*
* 開啓二級緩存步驟:
* 1.設置settings,<setting name="cacheEnabled" value="true"/>
* 2.在mapper文件裏面配置緩存的屬性
* <cache/>
* 3.測試
*
* 注意點:二級緩存是將整個對象以流的形式保存到緩存,全部須要序列化對象,須要讓實體類序列化
*
* */