开启mybatis日志_Mybatis源码分析之Cache二级缓存原理 (五)
生活随笔
收集整理的這篇文章主要介紹了
开启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二级缓存原理 (五)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python如何安装scrapy_Pyt
- 下一篇: formdata怎么传数组_如何使用fo