日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

詳解Mybatis的緩存

瀏覽:37日期:2023-10-20 12:33:49
Mybatis的緩存

mybatis是一個查詢數據庫的封裝框架,主要是封裝提供靈活的增刪改sql,開發中,service層能夠通過mybatis組件查詢和修改數據庫中表的數據;作為查詢工具,mybatis有使用緩存,這里講一下mybatis的緩存相關源碼。

緩存

在計算機里面,任何信息都有源頭,緩存一般指源頭信息讀取后,放在內存或者其他讀取較快的地方,下次讀取相同信息不去源頭查詢而是直接從內存(或者能快速存取的硬件)讀取。這樣可以減少硬件使用,提高讀取速度。

mybatis也是這樣,查詢數據庫的數據之后,mybatis可以把查詢結果緩存到內存,下次查詢如果查詢語句相同,并且查詢相關的表的數據沒被修改過,就可以直接返回緩存中的結果,而不用去查詢數據庫的語句,有效節省了時間。

簡單看一下mybatis一級緩存和二級緩存相關源碼,學習使用

一級緩存

通過查看源碼可知,一級緩存是綁定sqSsession中的,所以每次查詢sqlSession不同就失效,相同的sqlSession可以使用一級緩存。

mybatis默認sqlsession:org.apache.ibatis.session.defaults.DefaultSqlSession

構造方法中傳入executor(查詢執行對象)

public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) { this.configuration = configuration; this.executor = executor; this.dirty = false; this.autoCommit = autoCommit; }

executor中攜帶一級緩存成員:

protected BaseExecutor(Configuration configuration, Transaction transaction) { this.transaction = transaction; this.deferredLoads = new ConcurrentLinkedQueue<>(); this.localCache = new PerpetualCache('LocalCache'); //默認一級緩存 this.localOutputParameterCache = new PerpetualCache('LocalOutputParameterCache'); this.closed = false; this.configuration = configuration; this.wrapper = this; }查詢使用一級緩存邏輯

org.apache.ibatis.executor.BaseExecutor.query()

public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { ErrorContext.instance().resource(ms.getResource()).activity('executing a query').object(ms.getId()); List<E> list; try { queryStack++; //localCache 一級緩存 list = resultHandler == null ? (List<E>) localCache.getObject(key) : null; //先從一級緩存中獲取,key是通過sql語句生成 if (list != null) { handleLocallyCachedOutputParameters(ms, key, parameter, boundSql); } else { // 如果緩存中沒有 才從數據庫查詢 list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql); } } finally { queryStack--; } return list; } //從數據庫讀取數據 private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { List<E> list; localCache.putObject(key, EXECUTION_PLACEHOLDER); try { list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql); } finally { localCache.removeObject(key);//將一級緩存清除 } localCache.putObject(key, list);//返回查詢結果之前,先放入一級緩存 刷新 if (ms.getStatementType() == StatementType.CALLABLE) { localOutputParameterCache.putObject(key, parameter); } return list; }二級緩存

二級緩存mapper中的,默認是開啟的,但需要在映射文件mapper.xml中添加<cache/>標簽

<mapper namespace='userMapper'><cache/><!-- 添加cache標簽表示此mapper使用二級緩存 --></mapper>

配置false可以關閉二級緩存

二級緩存的解析

org.apache.ibatis.builder.xml.XMLMapperBuilder

private void configurationElement(XNode context) { try { //... cacheElement(context.evalNode('cache')); //解析cache標簽 } catch (Exception e) { throw new BuilderException('Error parsing Mapper XML. The XML location is ’' + resource + '’. Cause: ' + e, e); } } private void cacheElement(XNode context) { if (context != null) { // if hava cache tag 如果有cache標簽才執行下面的邏輯 String type = context.getStringAttribute('type', 'PERPETUAL'); Class<? extends Cache> typeClass = typeAliasRegistry.resolveAlias(type); String eviction = context.getStringAttribute('eviction', 'LRU'); Class<? extends Cache> evictionClass = typeAliasRegistry.resolveAlias(eviction); Long flushInterval = context.getLongAttribute('flushInterval'); Integer size = context.getIntAttribute('size'); boolean readWrite = !context.getBooleanAttribute('readOnly', false); boolean blocking = context.getBooleanAttribute('blocking', false); Properties props = context.getChildrenAsProperties(); builderAssistant.useNewCache(typeClass, evictionClass, flushInterval, size, readWrite, blocking, props);//建立二級緩存 } }

org.apache.ibatis.builder.MapperBuilderAssistant.useNewCache():

public Cache useNewCache(Class<? extends Cache> typeClass, Class<? extends Cache> evictionClass, Long flushInterval, Integer size, boolean readWrite, boolean blocking, Properties props) { Cache cache = new CacheBuilder(currentNamespace) .implementation(valueOrDefault(typeClass, PerpetualCache.class)) .addDecorator(valueOrDefault(evictionClass, LruCache.class)) .clearInterval(flushInterval) .size(size) .readWrite(readWrite) .blocking(blocking) .properties(props) .build(); configuration.addCache(cache);//二級緩存賦值,如果cache標簽為空,不會執行此方法,currentCache為空 currentCache = cache; return cache; }

在映射文件mapper中如果沒有cache標簽,不會執行上面的useNewCache方法,cache為null,就不會使用二級緩存(相當于失效)。

查詢使用二級緩存邏輯

org.apache.ibatis.executor.CachingExecutor :

@Override public <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) {//如果二級緩存對象不為空 嘗試在二級緩存中獲取(沒有cache標簽此對象就是空) flushCacheIfRequired(ms); if (ms.isUseCache() && resultHandler == null) { ensureNoOutParams(ms, boundSql); @SuppressWarnings('unchecked') List<E> list = (List<E>) tcm.getObject(cache, key); //從二級緩存中獲取數據 if (list == null) { list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); //如果為空,使用delegate查詢(BaseExecutor) tcm.putObject(cache, key, list); // 查詢結果保存到二級緩存 } return list; } } return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); }

二級緩存和一級緩存不用想,數據庫的數據被修改是要清空緩存的,不然數據有誤,至于怎么清空,是另一套邏輯了,mapper中的cache標簽可以配置一些參數,比如緩存定期清空。

一級二級緩存先后順序

mybatis默認是先查詢二級緩存,沒有,再查看一級緩存,都為空,最后查詢數據庫

以上就是詳解Mybatis的緩存的詳細內容,更多關于Mybatis的緩存的資料請關注好吧啦網其它相關文章!

標簽: Mybatis 數據庫
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩av在线免费观看不卡| 亚洲欧美视频一区二区三区| 日韩高清一区| 丝瓜av网站精品一区二区 | 97精品一区| 石原莉奈一区二区三区在线观看| 久久久久免费| 国产福利亚洲| 欧美一级全黄| 国产在视频一区二区三区吞精| 免费国产亚洲视频| 日韩影院精彩在线| 亚洲永久精品唐人导航网址| 亚洲欧洲日本mm| 99国产精品视频免费观看一公开| 国产99精品| 亚洲成人精品| 97国产成人高清在线观看| 久久中文字幕导航| 91精品国产福利在线观看麻豆| 一本大道色婷婷在线| 国产成人精品亚洲线观看| 九九九精品视频| 天堂中文av在线资源库| 成人午夜国产| 狠狠久久婷婷| 免费在线视频一区| 久久黄色影视| 欧美国产小视频| 正在播放日韩精品| 日韩久久视频| 亚洲人成精品久久久| 香蕉久久夜色精品国产| 伊人影院久久| 久久不射网站| 日欧美一区二区| 97精品国产| 亚洲一级影院| 免费的成人av| 亚洲精品一级| 国产精品天天看天天狠| 精品黄色一级片| 日本久久成人网| 美女91精品| 精品一区视频| 激情五月综合网| 日本aⅴ免费视频一区二区三区| 少妇高潮一区二区三区99| 久久97视频| 激情久久婷婷| 日本不卡高清| 欧美日韩夜夜| 国产一区观看| 日韩精品欧美成人高清一区二区| 国产精品视频一区二区三区| 国产成人精品免费视| 黄色精品视频| 免费中文字幕日韩欧美| 日韩av成人高清| 日韩精品第一区| 亚洲另类视频| 红桃视频欧美| 在线看片日韩| 丰满少妇一区| 亚洲一区成人| 久久免费国产| 日韩精选在线| 久久精品导航| 欧美精品国产白浆久久久久| 免播放器亚洲| 精品午夜av| 美女91精品| 国产一区二区久久久久| 日韩区欧美区| 黄色不卡一区| 欧美激情视频一区二区三区免费 | 免费在线观看一区二区三区| 国产精品主播| japanese国产精品| 黑森林国产精品av| 日本强好片久久久久久aaa| 久久精品成人| 麻豆一区二区三| 日韩动漫一区| 欧美在线资源| 激情国产在线| 美女久久久久久| 国产亚洲一区在线| 激情综合婷婷| 日本a级不卡| 首页亚洲欧美制服丝腿| 激情欧美国产欧美| 色欧美自拍视频| 清纯唯美亚洲综合一区| 在线综合欧美| 欧美午夜不卡| 成年男女免费视频网站不卡| 日韩精品中文字幕一区二区| 亚洲欧洲一区| 91成人精品视频| 日韩精品永久网址| 国产精品激情| 伊人久久亚洲热| aa亚洲婷婷| 久久狠狠婷婷| 国产一区二区三区四区五区| 久久精品 人人爱| 国产精品日韩精品在线播放| 亚洲91网站| 丝袜亚洲另类欧美| 精品一区免费| 丝袜美腿一区二区三区| 久久婷婷一区| 91视频一区| 精品国产三区在线| 狠狠久久伊人| 精品视频一区二区三区在线观看| 樱桃成人精品视频在线播放| 国产99亚洲| 日韩一级欧洲| 日韩午夜高潮| 99精品99| 丝袜美腿成人在线| 日韩不卡在线观看日韩不卡视频| 亚洲+小说+欧美+激情+另类| 久久先锋影音| 日韩午夜黄色| 亚洲91在线| 91成人福利| 国产精品久久| 精品国产日韩欧美精品国产欧美日韩一区二区三区 | 日韩一区三区| 欧美肉体xxxx裸体137大胆| 香蕉久久精品| 亚洲午夜在线| 国产亚洲精品久久久久婷婷瑜伽| 婷婷久久免费视频| 日日摸夜夜添夜夜添国产精品| 一区二区91| 日本va欧美va欧美va精品| 精品国产亚洲一区二区三区大结局 | 四虎影视精品| 亚洲第一精品影视| 欧美+日本+国产+在线a∨观看| 亚洲欧美日韩国产| 亚洲精一区二区三区| 国产欧美一区二区三区国产幕精品 | 国产亚洲福利| 奇米色欧美一区二区三区| 国产日产精品_国产精品毛片 | 一区在线观看| 蜜桃视频一区二区三区在线观看| 亚洲尤物av| 日韩精品视频一区二区三区| 成人国产精品久久| 久久久精品久久久久久96| 伊人精品在线| 婷婷综合福利| 精品午夜视频| 男女精品网站| 国产私拍福利精品视频二区| 岛国精品一区| 亚洲一级特黄| 欧美国产中文高清| 国产精品欧美三级在线观看| 韩国一区二区三区视频| 久久精品国产99久久| 综合视频一区| 欧美一区精品| 日韩国产一区二区三区| 日韩制服丝袜先锋影音| 日韩欧美另类一区二区| 免费精品视频在线| 国产精品三级| 今天的高清视频免费播放成人| 日本a级不卡| 亚洲福利久久| 日韩高清在线不卡| 香蕉成人av| 日韩欧美少妇| 国产精品最新自拍| 亚洲福利久久| 国产精品大片| 好看不卡的中文字幕| 欧美国产专区| 亚洲视频www| 精品久久久久中文字幕小说| 亚洲日本国产| 免费看av不卡| 国产精品黄网站| 亚洲一二三区视频| 亚洲精品中文字幕乱码| 久久久久久夜| 欧美黄色一区| 夜久久久久久| 日韩欧美字幕| a国产在线视频| 91中文字幕精品永久在线| 国产一区二区三区91| 欧美精品三级在线|