mybatis二级缓存默认未开启源码的问题

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

mybatis二级缓存默认未开启源码的问题

小小少年_   2022-11-22 我要评论

说明

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判断都无法进去,就会直接走一级缓存查询

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们