mybatis整合springboot报BindingException:Invalid bound statement (not found)异常解决
作者:沉泽·
一、前言
本文的mybatis是与springboot整合时出现的异常,若使用的不是基于springboot,解决思路也大体一样的。
二、从整合mybatis的三个步骤排查问题
但在这之前,我们先要知道整合mybatis的三个重要的工作,如此才能排查,且往下看。
2.1 pom.xml配置**Mapper.xml文件的构建路径
我们打开pom文件如下:
<build> <resources> <resource> <directory>src/main/java</directory> <filtering>false</filtering> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <filtering>false</filtering> <includes> <include>*</include> <include>**/*.xml</include> </includes> </resource> </resources> </build>
这部分代码的作用是指定需要编译到taget目录下的资源文件。我们的程序运行,都是执行编译好的taget目录下的内容,若taget里找不到xml文件资源就会报错Invalid bound statement (not found)。
每个人的项目配置都可能有些区别,但在这里我们只需要关注<includes>标签即可。还有对于不同的项目,xml的存放位置也可能不同,有的存在于src/main/java代码下,有的存在于src/main/resources。
<include>**/*.xml</include>
这行代码是用于构建存在于src/main/java代码中的xml文件。
<include></include>
<include>**/.xml</include>
这行代码是用于构建存在于src/main/resources代码中的所有文件。
上述,我们可以排查第一个可能抛出Invalid bound statement (not found)异常的情况,我们可以通过查看编译好的taget目录,如下:
情况一:
原代码文件目录:
编译失败的情况:
编译成功的情况:
情况二:
源代码文件目录:
编译失败:
编译成功:
有时,一直编译不成功,那就将taget重新删除,再编译。
2.2 配置mapper类的包扫描路径
这个步骤与Invalid bound statement (not found)异常无关,但是它也是整合mybatis重要的步骤之一,这里也说明一下,有两种方式实现,可根据自己的项目情况使用。(两者择其一)
通过注解的方式扫描:
通过配置类方式扫描:
这个步骤的目的是将我们定义的mapper类装配到我们的ioc容器中。
若没有扫描,启动时就会直接报找不到mapper的错误,无法运行项目。
2.3 application.yml文件中配置**Mapper.xml文件的扫描路径
这个配置若不正确,也会导致Invalid bound statement (not found)异常。值得一说的是,这一步骤的扫描是建立在步骤一的基础之上的,若编译好的taget目录都没有目标文件,那这一步骤就更不用说了。
一:
这里的扫描路径配置,还需要注意自己的项目使用的原始mybatis还是mybatis-plus,它们的配置也有区别的,如下:
原始mybatis:
mybatis: mapper-locations: classpath:/cn/anycase/demo/mapper/xml/*Mapper.xml
mybatis-plus:
mybatis-plus: mapper-locations: classpath:cn/anycase/demo/mapper/xml/*.xml
本例用的是mybatis-plus:
二:
使用mybatis-plus,当xml和mapper类在同级目录时可以省略这个扫描路径的配置,所以我们看到的有些项目少了这个配置(mybatis应该做了默认的扫描操作,这里不做深究),但它并没有错,且能正常运行。(原始mybatis是否也可以,本人未做相关测试)
三:
还有一个需要注意的点,前面步骤一说了,mapper.xml文件可能存在于src/main/java代码中,或存在于src/main/resources资源中,因此我们的配置路径也有所不同,如下:
Invalid bound statement (not found)这个异常,在常规下,通过上述的三个步骤可以百分百解决。
三、其他情况的Invalid bound statement (not found)异常
3.1 文件名导致的异常
上述截图的文件目录,在运行过程中也出现了Invalid bound statement (not found)异常,仔细检查了原代码xml、targe下的xml目录、yml中配置的扫描目录,看似正确了但其实是有问题的。
源代码目录的"mybatis.mapper"这个展示没问题,但target目录下的"mybatis.mapper"这个展示有问题,正常编译好的target文件目录都会是按层级展示的,但是这里确是连在了一起。所以发现问题了,就是在创建mybatis/mapper层级目录的时候,失误创建了名字为"mybatis.mapper"目录。
解决方案:删除mybatis.mapper,重新建立,先建mybatis文件夹,再建立mapper文件夹,最后再建立.xml文件。
3.2 因为扩展的配置类导致yml扫描路径配置不生效
这是另一种出现Invalid bound statement (not found)异常的情况,如下截图
如图所示,我们的各项步骤和配置都检查,仍旧不发现任何问题,但一当运行时就会报错,这很让人百思不得其解。。。。。但其实问题肯定是出在配置里头,是不是哪个地方出现了覆盖,导致扫描路径不生效?
有了这个想法,我们就可以检查源代码中的所有关于mybatis的配置类。最后,我们发现了一个类,如下:
源代码:
@Configuration public class MybatisPlusConfig implements EnvironmentAware { Environment env; @Bean("primary") @Primary public DataSource dataSource() throws ClassNotFoundException { return DataSourceBuilder.create() .url(env.getProperty("spring.datasource.url")) .type((Class<? extends DataSource>) Class.forName(env.getProperty("spring.datasource.type"))) .driverClassName(env.getProperty("spring.datasource.driverClassName")) .username(env.getProperty("spring.datasource.username")) .password(env.getProperty("spring.datasource.password")) .build(); } @Bean("mainsf") public SqlSessionFactory sqlSessionFactory(@Qualifier("primary") DataSource dataSource, GlobalConfiguration globalConfiguration) throws Exception { MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean(); sqlSessionFactory.setDataSource(dataSource); MybatisConfiguration configuration = new MybatisConfiguration(); configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class); configuration.setJdbcTypeForNull(JdbcType.NULL); configuration.setMapUnderscoreToCamelCase(true); sqlSessionFactory.setConfiguration(configuration); Interceptor[] plugins; plugins = new Interceptor[]{new PaginationInterceptor()}; sqlSessionFactory.setPlugins(plugins); sqlSessionFactory.setGlobalConfig(globalConfiguration); return sqlSessionFactory.getObject(); } @Bean public GlobalConfiguration globalConfiguration() { GlobalConfiguration conf = new GlobalConfiguration(); conf.setIdType(1); return conf; } @Override public void setEnvironment(Environment environment) { this.env = environment; } }
问题就发现了,这个配置类中自定义了一个SqlSessionFactory ,里边也配置了MybatisConfiguration相关的东西,因此我们yml里面的配置mybatis-plus. mapper-locations便失效了。
- 解决方案一:将这个配置类里相关的mybatis配置去掉。
- 解决方案二:将xml挪到mapper类的同级目录下。(因为默认会扫描mapper类的同级xml)
3.3 方法名和statement ID需要一致
这个错误是比较没水准,这里不做赘述。
总结
到此这篇关于mybatis整合springboot报BindingException:Invalid bound statement (not found)异常解决的文章就介绍到这了,更多相关BindingException:Invalid bound statement (not found)内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章:
- 解决java中mybatis报错:org.apache.ibatis.binding.BindingException:Invalid bound statement(not found):xx问题
- 使用mybatis报Invalid bound statement解决分析
- 解决微服务下Mybatis xml无效绑定问题及分析Invalid bound statement
- mybatis创建项目报Invalid bound statement (not found)错误解决方法
- SpringBoot使用MyBatis-Plus解决Invalid bound statement异常
- 解决mybatis-plus通用mapper调用报错:Invalid bound statement
- mybatis Invalid bound statement(not found)排坑记录