org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)问题,即在mybatis中dao接口与mapper配置文件在做映射绑定的时候接口与xml不匹配,要么是找不到,要么是找到了却匹配不到。
我的问题是项目没有把最新的方法xml打包进项目,mybatis-plus从xml中找到与dao对应的接口名称。按第6种方法解决了。
若大家遇到这个错,首页到项目打到处检查mapper的xml中是否有最新方法。不然,你按网上的方法查找很久才能找到问题点。
我的maven项目引入mybatis-plus的pom.xml配置如下:
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency>
我的yml配置如下:
mybatis-plus:configuration:map-underscore-to-camel-case: trueauto-mapping-behavior: full# log-impl: org.apache.ibatis.logging.stdout.StdOutImplmapper-locations: classpath*:/**/mapper/**/*.xmltype-aliases-package: com.tfq.dao
我在CategoryBrandRelationDao.xml中添加了一个方法updateCategory。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.tfq.dao.CategoryBrandRelationDao"><!-- 可根据自己的需求,是否要使用 --><resultMap type="com.tfq.entity.CategoryBrandRelationEntity" id="categoryBrandRelationMap"><result property="id" column="id"/><result property="brandId" column="brand_id"/><result property="catelogId" column="catelog_id"/><result property="brandName" column="brand_name"/><result property="catelogName" column="catelog_name"/></resultMap><update id="updateCategory">UPDATE pms_category_brand_relationSET catelog_name=#{name}WHERE catelog_id = #{catId}</update></mapper>
于是我google搜可能出现的问题,按网上汇总问题依次排查:
1、检查xml文件的namespace是否对应接口,要是全路径。
xml文件名不需要和接口名一致,namespace和接口全类名一致即可。
2、xml中的函数id和接口中的函数名是否对得上,参数类型、返回值类型是否对得上
3、去看输出目录中有没有xml映射文件,maven项目默认把资源文件放在src/main/resources下,默认只识别src/main/resources下的资源文件。
如果你把xml映射文件等资源文件放到src/main/java的某个目录下,识别不了,需要在pom.xml中配置一下:
<resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include><include>**/*.properties</include></includes><filtering>true</filtering></resource><resource><directory>src/main/resources</directory><includes><include>**/*.xml</include><include>**/*.properties</include></includes><filtering>true</filtering></resource></resources>
4、看一下mybatis的配置在yml中对不对
我的项目yml配置在上面已贴出来。
我的mapper.xml文件都放到resources的标红目录。而Sprinboot启动时 log中Property 'mapperLocations' was not specified这句提示开始没引起了我的注意,后面找到是配置的xml的文件中update没被加载到Mybatis-plus的缓存中才看到。其实在yml中配置了mybatis-plus.mapper-locations=classpath*:**/mapper/xml/*.xml(没用),启动器没扫描到新加的xml中方法,十分奇怪。
注意:Maven 多模块项目的扫描路径需以 classpath*: 开头 (即加载多个 jar 包下的 XML 文件)
5、看一下xml映射文件是否带了后缀名.xml
这个很容易被忽略,一次SpringBoot中使用MyBatis时我调了半天,其它可能性都被排除了,愣是找不到原因,最后发现是我创建映射文件时直接输入UserDaoMapper,没带后缀.xml。
你不带后缀.xml,IDEA根据文件内容能识别它是xml文件,显示的图标也是xml文件的,但不带.xml后缀就不是映射文件,运行时识别不了。
我按以上方法都试了,还是报相同错。这让我很纳闷。于我开始根据mybatis-plus报错的源代码进行debug,首先进入MybatisMapperMethod.java
public class MybatisMapperMethod {public MybatisMapperMethod(Class<?> mapperInterface, Method method, Configuration config) {//找dao接口与xml中配置的方法名称进行匹配入口this.command = new MapperMethod.SqlCommand(config, mapperInterface, method);this.method = new MapperMethod.MethodSignature(config, mapperInterface, method);}}
在进入MapperMethod.java类
public SqlCommand(Configuration configuration, Class<?> mapperInterface, Method method) {final String methodName = method.getName();final Class<?> declaringClass = method.getDeclaringClass();//这个方法从mapper的xml中加载所有的配置数据,然后把dao接口名称与xml中配置对比返回一个mapper对象。MappedStatement ms = resolveMappedStatement(mapperInterface, methodName, declaringClass,configuration);if (ms == null) {if (method.getAnnotation(Flush.class) != null) {name = null;type = SqlCommandType.FLUSH;} else {//如果查找的mapper对象为空就抛出dao接口与xml不一致。throw new BindingException("Invalid bound statement (not found): "+ mapperInterface.getName() + "." + methodName);}} else {name = ms.getId();type = ms.getSqlCommandType();if (type == SqlCommandType.UNKNOWN) {throw new BindingException("Unknown execution method for: " + name);}}}
在resolveMappedStatement方法
private MappedStatement resolveMappedStatement(Class<?> mapperInterface, String methodName,Class<?> declaringClass, Configuration configuration) {String statementId = mapperInterface.getName() + "." + methodName;//特别注意configuration,它是加载你项目中配置的所有mapper的xml,若你发现这里面没有,//则是项目启动时没有把xml最新数据加载,然后去检查你的配置。if (configuration.hasStatement(statementId)) {return configuration.getMappedStatement(statementId);} else if (mapperInterface.equals(declaringClass)) {return null;}//后面代码省略...
}
解决方法
6.将配置文件放在 resource 文件夹中,对于 Maven 项目,可指定 POM 文件的 resource
<build><resources><!--指定资源的位置(xml放在resources下,可以不用指定)--><resource><directory>src/main/resources</directory></resource></resources>
</build>
加了这个配置,项目clean--->compile---->package,要你的项目就有最新的mapper的xml方法了。
参考blog:
mybatis-plus配置找不到Mapper接口路径的坑_mybatis-plus.mapper-locations-CSDN博客
https://www.cnblogs.com/chy18883701161/p/12695356.html
IDEA使用mybatis-plus 时出现的问题 Property ‘mapperLocations‘ was not specified &Invalid bound statement_property "mapperlocations-CSDN博客