mybatis二级缓存默认未开启源码的问题
小小少年_ 人气:0说明
mybatis的二级缓存,我们通常说,默认是关闭的,这个结论是没有问题的,但是我觉得有几个点需要说明白
二级缓存的时候,需要有几个配置必须开启,二级缓存才会生效
- 1.全局配置文件中的cacheEnable属性设置为true
- 2.mapper.xml文件中,配置节点
- 3.mapper.xml文件中,select语句的useCache配置为true
这三者同时满足,才会使用二级缓存
上面这三个配置,在源码中,解析了之后,分别对应这三个类中的属性
我们知道,mybatis中的配置文件,在解析了之后,最终会把所有解析的结果,映射到一个类中org.apache.ibatis.session.Configuration
- 1.对应着 configuration.cacheEnabled属性
- 2.对应着 Configuration --> mappedStatements --> cache
- 3.对应着 Configuration --> mappedStatements --> useCache
我们常说二级缓存默认是关闭的,并不是说这三个配置默认都没有配置,翻了源码之后,默认不做任何配置的情况下:
- 1.全局配置文件中的CacheEnable属性,默认是true
- 2.mapper.xml文件中的节点如果没有配置, 那MappedStatement对象中的cache属性为null
- 3.如果select语句的useCache没有配置,select语句默认是true,其他是false
所以,虽然这种也是默认关闭的,但是我觉得需要说明白,并不是二级缓存用到的这几个属性默认都是false
源码
针对这三个配置,我们来看下默认的配置对应的源码
cacheEnable
对CacheEnable的解析是在
org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration
我们接着来看赋值的逻辑这里,如果props为空(就是在全局配置文件中没有配置settings节点),此时在给各个属性赋值的时候,分别指定了默认值,可以看到,cacheEnable属性值默认是true;所以这里可以证明
第一点
节点的解析
org.apache.ibatis.builder.xml.XMLMapperBuilder#configurationElement
由于我没有配置cache节点,所以,这里为null,不会执行下面的useNewCache方法,为了证明第二点这个说法,我们假设此时指定了cache节点,我们来看下useNewCache()方法中会做什么
可以看到,在useNewCache方法中,初始化了cache之后,会把cache赋值在当前类的一个属性中,currentCache;为什么要关注这个属性?
因为后面在给mappedStatement的cache属性赋值时,会使用currentCache;
截止到这里,我们只需要知道,如果在mapper.xml文件中,没有配置节点,那org.apache.ibatis.builder.MapperBuilderAssistant#currentCache这个属性就是null
useCache的解析
org.apache.ibatis.builder.xml.XMLStatementBuilder#parseStatementNode
这个方法是解析了一个sql段之后的逻辑,可以看到,这里所有的属性,都是我们在中可以设置的,其中有一个useCache属性
看下这里的意思:
- 如果useCache这个属性为null,就会直接返回def 就是默认值,可以看到这里的默认值是isSelect;isSelect是在上面赋值的,如果当前是select语句,就是true,如果当前是非select,就是false;
其含义是:
- 如果没有配置useCache属性,select语句默认使用二级缓存,其他语句不使用
这里只是给useCache赋值了,我们看下在哪里把这个赋值放到了mappedStatement对象中
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
resultSetTypeEnum, flushCache, useCache, resultOrdered,
keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
在解析了所有的属性之后,会调用这个方法,给mappedStatent对象赋值
在赋值这里,有两个重要的代码段
第一个是使用useCache赋值,这里使用的就是前面入参的;使用currentCache给cache属性赋值,我们前面有说过,如果在mapper.xml文件中,没有配置节点,那此时的currentCache就是null
第二个:是把当前的mappedStatement对象添加到configuration的mappedStatements属性中
使用二级缓存源码
所以以上可以证明这三个配置对应的默认值,我们再来看下,sql在真正执行时,是如何使用二级缓存的
上面有说过,默认的CacheEnable属性默认是true,所以在初始化executor对象的时候,默认会初始化CachingExecutor对象,所以,无论是否使用了二级缓存,都会先调用到cachingExecutor对象中
可以看到,在真正调用二级缓存前,会有两层判断,分别是cache和useCache;这两个配置,cache默认是null,useCache默认是true,默认情况下,第一个if判断都无法进去,就会直接走一级缓存查询
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
加载全部内容