MyBatis 学习记录5 MyBatis的二级缓存

 

 

 

主题

  之前学习了一下MyBatis的一级缓存,主要涉及到BaseExecutor这个类. 现在准备学习记录下MyBatis二级缓存.

配置二级缓存与初始化发生的事情

首先二级缓存默认是不开启的,需要自己配置开启.

如上图,需要在configuration里去开启.

其次在需要用到二级缓存的Mapper的配置里做一些操作,如下图,增加一个cache节点

至此就可以在UserMapper上开启二级缓存了.

当MaBatis初始化的时候,需要解析各种XML配置来生成SQLSessionFactory,解析Mapper的配置也是其中一环.而解析Mapper的配置中,解析Cache又是其中的一部分.

这个解析cache会做什么事情呢?

如上图所示,会往builderAssistant里去新建一个Cache对象.其中Cache类的设计也是装饰着模式,层层嵌套.比如其中会包裹一个打印缓存命中信息的LoggingCache等等.

 

MapperBuilderAssistant是个Builder模式,解析Mapper的最后会调用assistant的addMappedStatement方法.

 1     public MappedStatement addMappedStatement(
 2             String id,
 3             SqlSource sqlSource,
 4             StatementType statementType,
 5             SqlCommandType sqlCommandType,
 6             Integer fetchSize,
 7             Integer timeout,
 8             String parameterMap,
 9             Class<?> parameterType,
10             String resultMap,
11             Class<?> resultType,
12             ResultSetType resultSetType,
13             boolean flushCache,
14             boolean useCache,
15             boolean resultOrdered,
16             KeyGenerator keyGenerator,
17             String keyProperty,
18             String keyColumn,
19             String databaseId,
20             LanguageDriver lang,
21             String resultSets) {
22 
23         if (unresolvedCacheRef) {
24             throw new IncompleteElementException("Cache-ref not yet resolved");
25         }
26 
27         id = applyCurrentNamespace(id, false);
28         boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
29 
30         MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType)
31                 .resource(resource)
32                 .fetchSize(fetchSize)
33                 .timeout(timeout)
34                 .statementType(statementType)
35                 .keyGenerator(keyGenerator)
36                 .keyProperty(keyProperty)
37                 .keyColumn(keyColumn)
38                 .databaseId(databaseId)
39                 .lang(lang)
40                 .resultOrdered(resultOrdered)
41                 .resultSets(resultSets)
42                 .resultMaps(getStatementResultMaps(resultMap, resultType, id))
43                 .resultSetType(resultSetType)
44                 .flushCacheRequired(valueOrDefault(flushCache, !isSelect))
45                 .useCache(valueOrDefault(useCache, isSelect))
46                 .cache(currentCache);
47 
48         ParameterMap statementParameterMap = getStatementParameterMap(parameterMap, parameterType, id);
49         if (statementParameterMap != null) {
50             statementBuilder.parameterMap(statementParameterMap);
51         }
52 
53         MappedStatement statement = statementBuilder.build();
54         configuration.addMappedStatement(statement);
55         return statement;
56     }
View Code

把刚才new出来的cache设置到MappedStatement.Builder中,最后build出一个MappedStatement,并添加到Configuration里. 如下图

所以其实我们刚才在Mapper的XML里配置的cache,最后生成对应的java Cache对象,是放在MappedStatement里的,而MappedStatement是什么东西? 看了如下3个截图大家应该就明白了.就是你XML里配置的一个一个DML对应的节点,当然1个Mapper.XML里会有很多这样的节点,而他们是公用1个Cache的.

MappedStatement是全局唯一的对象,被放到了Configuration里,不同的Executor需要用到的时候都回从Configuration里去找SQL对应的MappedStatement.

 

CachingExecutor

正如之前文章记录的那样,CachingExecutor是包裹在BaseExecutor外的一层Executor,使用的是装饰着模式. 二级缓存主要是在它里面实现的.

猜你喜欢

转载自www.cnblogs.com/abcwt112/p/9785816.html