自定义SqlSessionFactoryBean导致 mapper-locations 失效-阿里云开发者社区

开发者社区> Java技术进阶> 正文

自定义SqlSessionFactoryBean导致 mapper-locations 失效

简介:

问题重现

步骤
1,把所有的mapper xml移动到 /xxx/yyy/src/main/resources/mybatis/mapperxml 中;
2,修改application.properties ,添加:

mybatis.mapper-locations=classpath:**/mapperxml/*.xml

3,启动springboot 程序 com/test/xxx/app/nnn/Application.java
4,访问接口 http://127.0.0.1:/nnn/productManage/listYYs.json?ccKey=Key222&vvName=%AF%B7%E5%81%87App

报错:

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):

初步分析

根据现象推断出,spring boot 没有读取我的 mybatis mapper xml文件

image.png | left | 634x226

所以需要找出来,读取mybatis mapper xml文件 的逻辑在哪里,为什么没有读取?

定位问题过程

读取mapper xml文件 的逻辑/位置

/repository/org/mybatis/mybatis-spring/1.3.2/mybatis-spring-1.3.2-sources.jar!/org/mybatis/spring/SqlSessionFactoryBean.java的
protected SqlSessionFactory buildSqlSessionFactory() throws IOException 方法中

image.png | left | 470x82.37871674491393

读取mapper xml文件的逻辑

if (!isEmpty(this.mapperLocations)) {
      for (Resource mapperLocation : this.mapperLocations) {
        if (mapperLocation == null) {
          continue;
        }
          XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
              configuration, mapperLocation.toString(), configuration.getSqlFragments());
          xmlMapperBuilder.parse();
      }
    } else {
      if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Property 'mapperLocations' was not specified or no matching resources found");
      }
    }

通过IDEA 调试到这儿的时候,发现 this.mapperLocations 为null,所以才没有走这个逻辑

为什么this.mapperLocations 为null

this.mapperLocations 是在哪里设置的呢?

在 org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration 类中,

sqlSessionFactory(DataSource dataSource)

image.png | left | 747x101

设置this.mapperLocations的代码:

 if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
      factory.setMapperLocations(this.properties.resolveMapperLocations());
    }

之所以没有执行MybatisAutoConfiguration 中的 sqlSessionFactory(DataSource dataSource) throws Exception 方法,是因为

SqlSessionFactoryBean

是我们定制的,没有依赖系统生成.

我们自定义生成SqlSessionFactoryBean 对象

final SqlSessionFactoBean sessionFactoryBean = new SqlSessionFactoBean();

sessionFactoryBean.setDataSource(aaaGroupDataSource);

SqlSessionFactory sqlSessionFactory = sessionFactoryBean.getObject();
// mybatis自动通用字段自动设置配置
org.apache.ibatis.session.Configuration configuration = sqlSessionFactory.getConfiguration();

return sqlSessionFactory;

系统构造SqlSessionFactory

在/repository/org/mybatis/mybatis-spring/1.3.6/mybatis-spring-1.3.6-sources.jar!/org/mybatis/spring/SqlSessionFactoryBean.java 的

protected SqlSessionFactory buildSqlSessionFactory() throws IOException

原因总结

因为我们自定义生成 SqlSessionFactoryBean对象 导致没有执行org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration 类的sqlSessionFactory(DataSource dataSource)方法

解决方法

手动添加设置this.mapperLocations 的逻辑即可:

final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();

//解决 application.properties 中 配置mybatis.mapper-locations 失效的问题
if (!ObjectUtils.isEmpty(this.mybatisProperties.resolveMapperLocations())) {
    sessionFactoryBean.setMapperLocations(this.mybatisProperties.resolveMapperLocations());
}
sessionFactoryBean.setDataSource(aaaGroupDataSource);

SqlSessionFactory sqlSessionFactory = sessionFactoryBean.getObject();
// mybatis自动通用字段自动设置配置
org.apache.ibatis.session.Configuration configuration = sqlSessionFactory.getConfiguration();
// 。。。

return sqlSessionFactory;

//解决 application.properties 中 配置mybatis.mapper-locations 失效的问题

    <span data-type="color" style="color:#F5222D">if (!ObjectUtils.isEmpty(this.mybatisProperties.resolveMapperLocations())) {</span>

sessionFactoryBean.setMapperLocations(this.mybatisProperties.resolveMapperLocations());
}

tips

若想亲自调试,可以关注如下类:

  1. org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
  2. org.mybatis.spring.SqlSessionFactoryBean
  3. org.apache.ibatis.session.SqlSessionFactoryBuilder

版权声明:本文首发在云栖社区,遵循云栖社区版权声明:本文内容由互联网用户自发贡献,版权归用户作者所有,云栖社区不为本文内容承担相关法律责任。云栖社区已升级为阿里云开发者社区。如果您发现本文中有涉嫌抄袭的内容,欢迎发送邮件至:developer2020@service.aliyun.com 进行举报,并提供相关证据,一经查实,阿里云开发者社区将协助删除涉嫌侵权内容。

分享:
Java技术进阶
使用钉钉扫一扫加入圈子
+ 订阅

Java技术进阶成长,课程资料,案例解析,实战经验全都有!

官网链接