亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發(fā) > Java > 正文

深入了解MyBatis二級緩存

2024-07-14 08:43:19
字體:
供稿:網(wǎng)友

一、創(chuàng)建Cache的完整過程

我們從SqlSessionFactoryBuilder解析mybatis-config.xml配置文件開始:

Reader reader = Resources.getResourceAsReader("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);

然后是:

XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);return build(parser.parse());

看parser.parse()方法:

parseConfiguration(parser.evalNode("/configuration"));

看處理Mapper.xml文件的位置:

mapperElement(root.evalNode("mappers"));

看處理Mapper.xml的XMLMapperBuilder:

XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration,    resource, configuration.getSqlFragments());mapperParser.parse();

繼續(xù)看parse方法:

configurationElement(parser.evalNode("/mapper"));

到這里:

String namespace = context.getStringAttribute("namespace");if (namespace.equals("")) { throw new BuilderException("Mapper's namespace cannot be empty");}builderAssistant.setCurrentNamespace(namespace);cacheRefElement(context.evalNode("cache-ref"));cacheElement(context.evalNode("cache"));

從這里看到namespace就是xml中<mapper>元素的屬性。然后下面是先后處理的cache-ref和cache,后面的cache會覆蓋前面的cache-ref,但是如果一開始cache-ref沒有找到引用的cache,他就不會被覆蓋,會一直到最后處理完成為止,最后如果存在cache,反而會被cache-ref覆蓋。這里是不是看著有點暈、有點亂?所以千萬別同時配置這兩個,實際上也很少有人會這么做。

看看MyBatis如何處理<cache/>:

private void cacheElement(XNode context) throws Exception {  if (context != null) {    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);  }}

從源碼可以看到MyBatis讀取了那些屬性,而且很容易可以到這些屬性的默認值。

創(chuàng)建Java的cache對象方法為builderAssistant.useNewCache,我們看看這段代碼:

public Cache useNewCache(Class<? extends Cache> typeClass,             Class<? extends Cache> evictionClass,             Long flushInterval,             Integer size,             boolean readWrite,             boolean blocking,             Properties props) {  typeClass = valueOrDefault(typeClass, PerpetualCache.class);  evictionClass = valueOrDefault(evictionClass, LruCache.class);  Cache cache = new CacheBuilder(currentNamespace)      .implementation(typeClass)      .addDecorator(evictionClass)      .clearInterval(flushInterval)      .size(size)      .readWrite(readWrite)      .blocking(blocking)      .properties(props)      .build();  configuration.addCache(cache);  currentCache = cache;  return cache;}

從調(diào)用該方法的地方,我們可以看到并沒有使用返回值cache,在后面的過程中創(chuàng)建MappedStatement的時候使用了currentCache。

二、使用Cache過程

在系統(tǒng)中,使用Cache的地方在CachingExecutor中:

@Overridepublic <E> List<E> query(    MappedStatement ms, Object parameterObject,     RowBounds rowBounds, ResultHandler resultHandler,     CacheKey key, BoundSql boundSql) throws SQLException { Cache cache = ms.getCache();

獲取cache后,先判斷是否有二級緩存。

只有通過<cache/>,<cache-ref/>或@CacheNamespace,@CacheNamespaceRef標記使用緩存的Mapper.xml或Mapper接口(同一個namespace,不能同時使用)才會有二級緩存。

 if (cache != null) {

如果cache存在,那么會根據(jù)sql配置(<insert>,<select>,<update>,<delete>的flushCache屬性來確定是否清空緩存。

  flushCacheIfRequired(ms);

然后根據(jù)xml配置的屬性useCache來判斷是否使用緩存(resultHandler一般使用的默認值,很少會null)。

  if (ms.isUseCache() && resultHandler == null) {

確保方法沒有Out類型的參數(shù),mybatis不支持存儲過程的緩存,所以如果是存儲過程,這里就會報錯。

   ensureNoOutParams(ms, parameterObject, boundSql);

沒有問題后,就會從cache中根據(jù)key來取值:

   @SuppressWarnings("unchecked")   List<E> list = (List<E>) tcm.getObject(cache, key);

如果沒有緩存,就會執(zhí)行查詢,并且將查詢結(jié)果放到緩存中。

   if (list == null) {    list = delegate.<E>query(ms, parameterObject,       rowBounds, resultHandler, key, boundSql);    tcm.putObject(cache, key, list); // issue #578 and #116   }

返回結(jié)果

   return list;  } }

沒有緩存時,直接執(zhí)行查詢

 return delegate.<E>query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);}

在上面的代碼中tcm.putObject(cache, key, list);這句代碼是緩存了結(jié)果。但是實際上直到sqlsession關(guān)閉,MyBatis才以序列化的形式保存到了一個Map(默認的緩存配置)中。

三、Cache使用時的注意事項

1. 只能在【只有單表操作】的表上使用緩存

不只是要保證這個表在整個系統(tǒng)中只有單表操作,而且和該表有關(guān)的全部操作必須全部在一個namespace下。

2. 在可以保證查詢遠遠大于insert,update,delete操作的情況下使用緩存

這一點不需要多說,所有人都應(yīng)該清楚。記住,這一點需要保證在1的前提下才可以!

四、避免使用二級緩存

可能會有很多人不理解這里,二級緩存帶來的好處遠遠比不上他所隱藏的危害。

  • 緩存是以namespace為單位的,不同namespace下的操作互不影響。
  • insert,update,delete操作會清空所在namespace下的全部緩存。
  • 通常使用MyBatis Generator生成的代碼中,都是各個表獨立的,每個表都有自己的namespace。

為什么避免使用二級緩存

在符合【Cache使用時的注意事項】的要求時,并沒有什么危害。

其他情況就會有很多危害了。

針對一個表的某些操作不在他獨立的namespace下進行。

例如在UserMapper.xml中有大多數(shù)針對user表的操作。但是在一個XXXMapper.xml中,還有針對user單表的操作。

這會導致user在兩個命名空間下的數(shù)據(jù)不一致。如果在UserMapper.xml中做了刷新緩存的操作,在XXXMapper.xml中緩存仍然有效,如果有針對user的單表查詢,使用緩存的結(jié)果可能會不正確。

更危險的情況是在XXXMapper.xml做了insert,update,delete操作時,會導致UserMapper.xml中的各種操作充滿未知和風險。

有關(guān)這樣單表的操作可能不常見。但是你也許想到了一種常見的情況。

多表操作一定不能使用緩存

為什么不能?

首先不管多表操作寫到那個namespace下,都會存在某個表不在這個namespace下的情況。

例如兩個表:role和user_role,如果我想查詢出某個用戶的全部角色role,就一定會涉及到多表的操作。

<select id="selectUserRoles" resultType="UserRoleVO"> select * from user_role a,role b where a.roleid = b.roleid and a.userid = #{userid}</select>

像上面這個查詢,你會寫到那個xml中呢??

不管是寫到RoleMapper.xml還是UserRoleMapper.xml,或者是一個獨立的XxxMapper.xml中。如果使用了二級緩存,都會導致上面這個查詢結(jié)果可能不正確。

如果你正好修改了這個用戶的角色,上面這個查詢使用緩存的時候結(jié)果就是錯的。

這點應(yīng)該很容易理解。

在我看來,就以MyBatis目前的緩存方式來看是無解的。多表操作根本不能緩存。

如果你讓他們都使用同一個namespace(通過<cache-ref>)來避免臟數(shù)據(jù),那就失去了緩存的意義。

看到這里,實際上就是說,二級緩存不能用。整篇文章介紹這么多也沒什么用了。

五、挽救二級緩存?

想更高效率的使用二級緩存是解決不了了。

但是解決多表操作避免臟數(shù)據(jù)還是有法解決的。解決思路就是通過攔截器判斷執(zhí)行的sql涉及到那些表(可以用jsqlparser解析),然后把相關(guān)表的緩存自動清空。但是這種方式對緩存的使用效率是很低的。

設(shè)計這樣一個插件是相當復(fù)雜的,既然我沒想著去實現(xiàn),就不廢話了。

最后還是建議,放棄二級緩存,在業(yè)務(wù)層使用可控制的緩存代替更好。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VeVb武林網(wǎng)的支持。


注:相關(guān)教程知識閱讀請移步到JAVA教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
亚洲午夜久久久久久久久久久| 99精品国产在热久久下载| 2021天堂中文幕一二区在线观| 激情成人在线观看| 久久久久久久久久av| 日韩精品乱码av一区二区| 国产伦精品一区二区三区视频金莲| 最近高清中文在线字幕在线观看1| 久久国产乱子精品免费女| 91禁在线看| 911国产在线| 永久av免费在线观看| 色猫猫国产区一区二在线视频| 日本黄色特级片| 国产成人涩涩涩视频在线观看| 成人影音在线| 97影院秋霞午夜在线观看| 99在线精品免费视频| 国产风韵犹存在线视精品| 大肉大捧一进一出好爽| 亚洲欧美日韩国产综合在线| 亚洲综合免费观看高清完整版在线| 国产xxxx孕妇| 99久久久免费精品| 青青青青草视频| 亚洲奶大毛多的老太婆| 欧美丝袜丝交足nylons| 欧美性猛交xxxx免费看| 成人日韩在线电影| 国产a级一级片| 国内精品视频一区| 午夜精品久久一牛影视| 中国日韩欧美久久久久久久久| 国产一级特黄视频| 亚洲一区二区免费视频软件合集| 人操人视频在线观看| 美女又爽又黄视频毛茸茸| 成人黄色免费| 丰满少妇一区二区三区| 国产精品久久久视频| 99三级在线| 99精品视频中文字幕| 亚洲精品视频一区二区| 欧美一区二粉嫩精品国产一线天| 欧美成人在线免费| 欧美一级免费片| 国产乱在线观看完整版视频| 亚洲成人黄色片| 国产视频一区二区| 免费男女羞羞的视频网站中文字幕| 国产色在线播放| 亚洲怡红院在线观看| 欧美国产第二页| 日韩中文字幕组| 91视频 -- 69xx| 国产一区二区三区免费观看| 国产精品视频午夜| 欧美日韩国产中文精品字幕自在自线| 三级在线视频| 图片区偷拍区小说区| 粉嫩在线一区二区三区视频| 欧美寡妇性猛交xxx免费| 少妇黄色一级片| 欧美午夜理伦三级在线观看| 欧美一级视频精品观看| 91精品国产调教在线观看| 日韩大尺度在线观看| 51久久精品夜色国产麻豆| 香蕉视频在线观看www| 亚洲视频播放| 欧美二区乱c黑人| www亚洲人| 成人久久18免费网站图片| 怡红院精品视频在线观看极品| 色一情一区二区三区四区| 69ww免费视频播放器| 国产精品黄页网站在线播放免费| 日韩黄色影视| 青青草原亚洲| 99久久精品国产一区二区小说| 国产一区欧美二区| 美日韩免费视频| 久久一二三区| 国产日韩在线一区二区三区| 可播放的18gay1069| 91久久奴性调教| 国内精品久久久久久久影视简单| 成人免费视频毛片| 深夜福利久久| 成人综合网址| 国产一区二区三区四区尤物| 性高潮久久久久久久久久| 成人动漫一区| 欧美xxxxxxxxx59| 亚洲影院免费观看| 亚洲一区二区精品视频| 国产福利电影在线观看| 欧美超级免费视 在线| 亚洲激情第一区| 污污视频网站| 日韩精品一区二区三区中文字幕| 丁香婷婷久久久综合精品国产| 国产天堂在线播放视频| 日韩欧美亚洲| 精品免费视频| 国产成人精品亚洲男人的天堂| 免费一级片视频| 欧美第一页在线| 色综合小说天天综合网| 国产乡下妇女做爰| 蜜桃传媒一区二区亚洲| 精品国产1区| 成年免费视频黄网站在线观看| 国产成人精品免费网站| 国产丝袜不卡| 欧美另类极限扩张| 国产在线播精品第三| 成 人 黄 色 片 在线播放| av网站免费大全| 污香蕉视频在线观看| 婷婷丁香综合| 伊人久久成人网| 亚洲a一级视频| 中文字幕中文字幕中文字幕亚洲无线| 91免费版网站入口| 成人一区二区三区在线观看| 欧美性xxxxxbbbbbb精品| 欧美码中文字幕在线| 日韩电影在线观看一区二区| 国产视频在线观看一区二区| 国产喷水吹潮视频www| 国产二级片在线观看| 日韩欧美a级成人黄色| 免费看av大片| 国产成人精品一区二区三区网站观看| 国产精品va在线播放我和闺蜜| 一级在线免费观看| 国产免费永久在线观看| 国产白嫩美女无套久久| 日韩在线欧美在线国产在线| 91嫩草|国产丨精品入口| 日韩精品视频在线看| 成人动漫在线免费观看| 日本高清视频免费在线观看| 性色av一区二区咪爱| 在线观看免费av片| 55av亚洲| 麻豆疯狂做受xxxx高潮视频| 97在线看免费观看视频在线观看| 亚洲国产精品免费视频| 成人午夜精品视频| 成年网站免费视频黄| 熟妇熟女乱妇乱女网站| www在线视频观看| 国产高清在线精品一区二区三区| 久久久精品电影| 国产传媒久久文化传媒| 欧美黄色免费网站| 翁止熄痒禁伦短文合集免费视频| 最近高清中文在线字幕在线观看| 国产精品高潮久久| 91九色美女在线视频| 久久精品一区二区国产| 欧美理论一区二区| 国产美女三级视频| 国产精品av电影| 天堂视频福利| 亚洲午夜久久久久久久久| 久久久久成人网| 天天射天天色天天干| 又粗又大的机巴好爽欧美| 四虎成人精品免费影院| 亚洲国产中文字幕在线视频综合| 日韩一区二区三区在线视频| 国产黄色小视频在线| 欧美乱妇一区二区三区不卡视频| 在线播放成人| 97精品视频在线播放| 国产精品欧美一区二区三区不卡| 美美女免费毛片| 五月婷婷亚洲综合| 天堂中文字幕在线观看| 精品一区二区三区视频日产| 91精品入口蜜桃| 在线观看一区二区精品视频| 一级一片免费看| 午夜影院免费视频| 国产美女在线精品| 91精品国产91久久久久麻豆 主演| 污片视频在线免费观看| 久久久久一区二区| 午夜精品久久久久久久99热影院| 欧美性受xxxx白人性爽| 美女扒开大腿让男人桶| 久久高清无码视频| 久久久久亚洲精品| sm久久捆绑调教精品一区| 亚洲一区二区在线视频观看| 久久精品国产福利| 亚洲视频久久| 真实国产乱子伦对白视频| 成人免费网址在线| 亚洲国产精品成人久久综合一区| 特级黄国产片一级视频播放| 久操网在线观看| 韩日午夜在线资源一区二区| 久久人人97超碰精品888| 日韩av中文字幕在线免费观看| 欧美性xxxxxbbbbbb精品| 亚洲精品日产aⅴ| 欧美日韩国产麻豆| 亚洲av成人精品毛片| 婷婷综合久久| 日产国产高清一区二区三区| 日韩欧美一区二区在线视频| 久久久久一区二区三区| 天天综合91| 日韩av在线免费观看不卡| 麻豆亚洲av熟女国产一区二| 国产精品不卡一区二区三区| 台湾无码一区二区| www.色视频| 亚洲第一成人网站| www免费视频观看在线| 熟妇人妻系列aⅴ无码专区友真希| 99国内精品久久久久久久软件| 国产白丝网站精品污在线入口| 欧美aa一级| 国产免费成人在线| 亚洲色图偷拍| 欧美日韩中文字幕在线观看| 永久在线免费观看| 狠狠色狠狠色综合日日五| 日本韩国欧美在线| 国产精品性做久久久久久| 激情综合网五月| 五福影院新址进入www1378| 91产国在线观看动作片喷水| 亚洲污视频在线观看| 欧美综合亚洲图片综合区| 911精品美国片911久久久| 欧美本精品男人aⅴ天堂| 成人av资源| 日韩成人av网站| 理论片在线不卡免费观看| 俄罗斯毛片基地| 成人教育av| 韩日成人在线| 久久一区二区三区四区五区| 性欧美18一19性猛交| 日韩欧美国产二区| 欧美日韩性视频在线| 日本一区二区三区网站| 欧美大片在线播放| 啊啊啊啊啊啊啊视频在线播放| 国产精品合集一区二区| 久久精品久久国产| 中日韩免视频上线全都免费| 成人网6969conwww| 亚洲国产精品精华素| 香蕉视频在线免费看| 欧美女人性生活视频| 欧美三级午夜理伦三级在线观看| 亚洲中文字幕无码专区| 国产激情精品久久久第一区二区| 国产成人精品亚洲777人妖| 精品国产网站地址| 成人av蜜桃| 无码视频在线观看| 欧美精品一区二区三区在线| 国产精品毛片va一区二区三区| 91亚洲精品国产| 亚洲一区免费在线| 亚洲精品无码久久久久久| 天天爽天天狠久久久| 久久影院一区二区| 日本成人看片网址| 久久久无码中文字幕久...| 最近国语视频在线观看免费播放| 真实乱视频国产免费观看| 久久综合九色99| 日韩欧美一级二级三级久久久| 天天综合网站| 日本精品免费在线观看| gogogo高清免费观看在线视频| 国产艳妇疯狂做爰视频| 日产精品99久久久久久| 亚州国产精品视频| 黄色动漫免费网站| 91国产精品一区| 国产日韩精品在线看| 清纯唯美亚洲综合一区| 欧美成人se01短视频在线看| 久久一区二区三区电影| 亚洲人成无码网站久久99热国产| 午夜精品影视国产一区在线麻豆| 久久人人爽人人爽人人片av高清| 国产午夜精品免费一区二区三区| 日本aⅴ精品一区二区三区| 亚洲一级二级在线| 爱搞国产精品| 成人xxxxx色| 亚洲一区二区三区四区五区黄| 在线观看国产福利| 成人免费黄色av| 亚洲成人套图| 亚洲人成在线免费观看| 少妇精品放荡导航| 欧美一级夜夜爽| 久久久久九九九| 国产精品日韩高清| 国产白嫩美女无套久久| 希岛爱理一区二区三区av高清| 欧美中文字幕一二三四区| 欧美三级三级三级| 成年人在线观看视频免费| 在线中文字幕视频观看| 男插女免费视频| 日韩在线不卡av| 毛片免费在线观看| 黄色动漫免费网站| 国产91丝袜在线播放九色| 天堂网在线.www天堂在线| 国产又粗又猛又爽又黄的视频一| 日本免费黄视频| 18深夜视频在线观看| 91中文字幕精品永久在线| 国产免费av一区二区三区|