1. 一級緩存
默認開啓的是一級緩存爲SQLSelect級別(全局)。
- 只要做了insert、update、delete就會清除所有本地緩存(源碼調用的是clearLocalEhCache方法清除所有緩存)。
1.1 實際項目一個jvm中只存在1個SQLSeseeion?
- 每個線程都有自己的SQLSession實例。
sqlSession因爲線程不安全,所有不會共享。(底層使用的hashMap存儲的緩存,因爲hashMap線程不安全)。
代碼執行完後在 finally最終執行 中會執行closeSqlSession()方法清空緩存和當前線程。 session.colse();
- SqlSession和session共存亡(session也是隻會和當前回話用戶綁定,不會共享)。
2. 二級緩存
二級緩存爲mapper級別,需要在mapper.xml中開啓 <setting name="cacheEnabled" value="true" />
,並配置緩存過期策略 <cache evication="LRU" type=“二級緩存會被執行的類全路徑”>。
mybatis緩存源碼在CachingExecuor類中。
2.1 二級緩存過期策略
LRU:移除最長時間不被使用的對象。
FLFO:先進先出原則,按對象進入緩存的順序來移除。
...
3. mybatis緩存底層是HashMap集合存放的
key: sql語句加參數;
value: 查詢到的數據;
4. 一二級緩存執行流程:
第一次通過localCache方法查本地緩存緩存是否存在數據,
- 存在則返回數據
- 不存在則查詢db,並調用localCache方法添加到本地緩存;
5. 如何關閉一級緩存
方法1. 開啓二級緩存。
方法2. 調用clearCache方法清除緩存。(在執行select查詢後主動調用此方法,此方法會在insert、update語句中默認執行)。
6. 一級緩存在集羣中存在髒讀問題
解決 :一級緩存使用redis、EhCache,二級緩存用sqlSession。