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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

开启mybatis日志_Mybatis源码分析之Cache二级缓存原理 (五)

發布時間:2024/1/23 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 开启mybatis日志_Mybatis源码分析之Cache二级缓存原理 (五) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一:Cache類的介紹

講解緩存之前我們需要先了解一下Cache接口以及實現MyBatis定義了一個org.apache.ibatis.cache.Cache接口作為其Cache提供者的SPI(ServiceProvider Interface) ,所有的MyBatis內部的Cache緩存,都應該實現這一接口

Cache的實現類中,Cache有不同的功能,每個功能獨立,互不影響,則對于不同的Cache功能,這里使用了裝飾者模式實現。

看下cache的實現類,如下圖:

1.FIFOCache:先進先出算法 回收策略,裝飾類,內部維護了一個隊列,來保證FIFO,一旦超出指定的大小,
則從隊列中獲取Key并從被包裝的Cache中移除該鍵值對。

2.LoggingCache:輸出緩存命中的日志信息,如果開啟了DEBUG模式,則會輸出命中率日志。

3.LruCache:最近最少使用算法,緩存回收策略,在內部保存一個LinkedHashMap

4.ScheduledCache:定時清空Cache,但是并沒有開始一個定時任務,而是在使用Cache的時候,才去檢查時間是否到了。

5.SerializedCache:序列化功能,將值序列化后存到緩存中。該功能用于緩存返回一份實例的Copy,用于保存線程安全。

6.SoftCache:基于軟引用實現的緩存管理策略,軟引用回收策略,軟引用只有當內存不足時才會被垃圾收集器回收

7.SynchronizedCache:同步的緩存裝飾器,用于防止多線程并發訪問

8.PerpetualCache 永久緩存,一旦存入就一直保持,內部就是一個HashMap

9.WeakCache:基于弱引用實現的緩存管理策略

10.TransactionalCache 事務緩存,一次性存入多個緩存,移除多個緩存

11.BlockingCache 可阻塞的緩存,內部實現是ConcurrentHashMap

二:二級緩存初始化

Mybatis默認對二級緩存是關閉的,一級緩存默認開啟,如果需要開啟只需在mapper上加入

二級緩存是怎么初始化的呢?

我們在之前的文章里面(Mybatis源碼分析之SqlSessionFactory(一))分析了配置文件的加載,我們回到那邊來找到二級緩存的加載地方,一開始我就說了“如果需要開啟只需在mapper上加入

XMLConfigBuilder.parse-->parseConfiguration(XNode root)-->mapperElement(root.evalNode("mappers"))-->
mapperElement(XNode parent)

看下mapperElement的方法

private void mapperElement(XNode parent) throws Exception {
if (parent != ) {
for (XNode child : parent.getChildren) {
if ("package".equals(child.getName)) {
String mapperPackage = child.getStringAttribute("name");
configuration.addMappers(mapperPackage);
} else {
String resource = child.getStringAttribute("resource");
String url = child.getStringAttribute("url");
String mapperClass = child.getStringAttribute("class");
if (resource != && url == && mapperClass == ) {
ErrorContext.instance.resource(resource);
InputStream inputStream = Resources.getResourceAsStream(resource);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments);
mapperParser.parse;
} else if (resource == && url != && mapperClass == ) {
ErrorContext.instance.resource(url);
InputStream inputStream = Resources.getUrlAsStream(url);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments);
mapperParser.parse;
} else if (resource == && url == && mapperClass != ) {
Class mapperInterface = Resources.classForName(mapperClass);
configuration.addMapper(mapperInterface);
} else {
throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
}
}
}
}
}

這個時候我已經找到了mapper節點了,我們在看向前走

XMLMapperBuilder.mapperParser.parse

代碼如下

public void parse {
if (!configuration.isResourceLoaded(resource)) {
configurationElement(parser.evalNode("/mapper"));
configuration.addLoadedResource(resource);
bindMapperForNamespace;
}
parsePendingResultMaps;
parsePendingChacheRefs;
parsePendingStatements;
}

看到configurationElement(parser.evalNode("/mapper"));看到mapper節點了繼續走

private void configurationElement(XNode context) {
try {
String namespace = context.getStringAttribute("namespace");
if (namespace == || namespace.equals("")) {
throw new BuilderException("Mapper's namespace cannot be empty");
}
builderAssistant.setCurrentNamespace(namespace);
cacheRefElement(context.evalNode("cache-ref"));
cacheElement(context.evalNode("cache"));
parameterMapElement(context.evalNodes("/mapper/parameterMap"));
resultMapElements(context.evalNodes("/mapper/resultMap"));
sqlElement(context.evalNodes("/mapper/sql"));
buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
} catch (Exception e) {
throw new BuilderException("Error parsing Mapper XML. Cause: " + e, e);
}
}

到這里終于見到了他cacheElement(context.evalNode("cache"));

看源碼

private void cacheElement(XNode context) throws Exception {
if (context != ) {
String type = context.getStringAttribute("type 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的开启mybatis日志_Mybatis源码分析之Cache二级缓存原理 (五)的全部內容,希望文章能夠幫你解決所遇到的問題。

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