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: true
auto-mapping-behavior: full
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath*:/**/mapper/**/*.xml
type-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_relation
SET 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博客