日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Mybatis3.4.x技术内幕(二十二):Mybatis一级、二级缓存原理分析

發布時間:2025/3/20 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mybatis3.4.x技术内幕(二十二):Mybatis一级、二级缓存原理分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

Mybatis的一級緩存,指的是SqlSession級別的緩存,默認開啟;Mybatis的二級緩存,指的是SqlSessionFactory級別的緩存,需要配置。緩存是針對select來說的。

1、一級緩存

<configuration><settings><setting name="localCacheScope" value="SESSION|STATEMENT" /></settings> </configuration>

localCacheScope用于配置一級緩存的范圍,默認值是SESSION,表示SqlSession范圍;

如果配置為STATEMENT,則表示SqlSession范圍內的一個查詢范圍,但它并不是一個Statement實例范圍。

STATEMENT舉例:查詢Student對象發送一次sql查詢,緊接著再發一次sql查詢關聯的Teacher對象,這個完整過程稱之為一個查詢。

一級緩存默認開啟,且沒有全局關閉的配置開關。

<select ... flushCache="false" useCache="true|false"/>

flushCache:同時影響了一級、二級緩存,flushCache=true,會導致清空本條sql(當前MappedStatement)的一級、二級緩存,注意是當前的,不影響其他的MappedStatement。

useCache:配置本條MappedStatement是否使用二級緩存,useCache=true,從二級緩存中獲取,沒有獲取到,才從數據庫中獲取。

org.apache.ibatis.executor.CachingExecutor#query()方法源碼:

Cache cache = ms.getCache();if (cache != null) {// flushCache作用于二級緩存flushCacheIfRequired(ms);// useCache作用于二級緩存if (ms.isUseCache() && resultHandler == null) {ensureNoOutParams(ms, parameterObject, boundSql);@SuppressWarnings("unchecked")List<E> list = (List<E>) tcm.getObject(cache, key);if (list == null) {list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);tcm.putObject(cache, key, list); // issue #578 and #116}return list;}} return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);

org.apache.ibatis.executor.BaseExecutor#query()方法源碼:

if (queryStack == 0 && ms.isFlushCacheRequired()) {// flushCache作用于一級緩存clearLocalCache(); }

在執行update、insert、delete、flushCache="true"、commit、rollback、LocalCacheScope.STATEMENT等情況下,一級緩存就都會被清空。

緩存其實基本數據結構就是一個HashMap,緩存中是否存在緩存數據,依賴key的生成策略。

org.apache.ibatis.executor.BaseExecutor.createCacheKey()源碼。

@Overridepublic CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {CacheKey cacheKey = new CacheKey();cacheKey.update(ms.getId());cacheKey.update(Integer.valueOf(rowBounds.getOffset()));cacheKey.update(Integer.valueOf(rowBounds.getLimit()));cacheKey.update(boundSql.getSql());for (int i = 0; i < parameterMappings.size(); i++) {//...cacheKey.update(value);}}if (configuration.getEnvironment() != null) {// issue #176cacheKey.update(configuration.getEnvironment().getId());}return cacheKey;}

id:com.mybatis3.mappers.TeacherMapper.findTeacherById

key的生成策略:id + offset + limit + sql + param value +?environment id,這些值都相同,生成的key就相同。

2、二級緩存

<configuration><settings><setting name="cacheEnabled" value="true|false" /></settings> </configuration>

cacheEnabled=true表示二級緩存可用,但是要開啟話,需要在Mapper.xml內配置。

<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/> if (cacheEnabled) {executor = new CachingExecutor(executor); }

二級緩存通過CachingExecutor來實現,原理是緩存里存在,就返回,沒有就調用Executor delegate到數據庫中查詢。

org.apache.ibatis.executor.CachingExecutor.query()源碼。

@Overridepublic <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)throws SQLException {Cache cache = ms.getCache();if (cache != null) {flushCacheIfRequired(ms);if (ms.isUseCache() && resultHandler == null) {ensureNoOutParams(ms, parameterObject, boundSql);@SuppressWarnings("unchecked")List<E> list = (List<E>) tcm.getObject(cache, key);if (list == null) {list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);tcm.putObject(cache, key, list); // issue #578 and #116}return list;}}return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);}

FIFO:First In First Out先進先出隊列。

flushInterval="60000",間隔60秒清空緩存,這個間隔60秒,是被動觸發的,而不是定時器輪詢的。

size=512,表示隊列最大512個長度,大于則移除隊列最前面的元素,這里的長度指的是CacheKey的個數。

CacheKey的生成策略,和一級緩存相同,id + offset + limit + sql + param value +?environment id。

readOnly="true",表示任何獲取對象的操作,都將返回同一實例對象。如果readOnly="false",則每次返回該對象的拷貝對象,簡單說就是序列化復制一份返回。

二級緩存有一個非常重要的空間劃分策略:

namespace="com.mybatis3.mappers.TeacherMapper"

namespace="com.mybatis3.mappers.StudentMapper"

即,按照namespace劃分,同一個namespace,同一個Cache空間,不同的namespace,不同的Cache空間。

每當執行insert、update、delete,flushCache=true時,二級緩存都會被清空。

版權提示:文章出自開源中國社區,若對文章感興趣,可關注我的開源中國社區博客(http://my.oschina.net/zudajun)。(經過網絡爬蟲或轉載的文章,經常丟失流程圖、時序圖,格式錯亂等,還是看原版的比較好)

轉載于:https://my.oschina.net/zudajun/blog/747499

總結

以上是生活随笔為你收集整理的Mybatis3.4.x技术内幕(二十二):Mybatis一级、二级缓存原理分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。