解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)异常
1、问题描述
今天在把普通的SpringBoot项目改造成SpringBoot微服务分布式架构项目的时候遇到一个问题:
前端项目运行时显示500错误,无法显示,于是来到后台查看报错
消费者端如下:
提供者端:
具体报错:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.team.news.mapper.NewsDetailMapper.selectByExample
at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235) ~[mybatis-3.5.1.jar:3.5.1]
at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:53) ~[mybatis-3.5.1.jar:3.5.1]
at org.apache.ibatis.binding.MapperProxy.lambda$cachedMapperMethod$0(MapperProxy.java:62) ~[mybatis-3.5.1.jar:3.5.1]
我只复制了关键几行,其中指出问题的是:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.team.news.mapper.NewsDetailMapper.selectByExample
大概意思就是:错误绑定(没有找到):com.team.news.mapper.NewsDetailMapper.selectByExample
说我的NewsDetailMapper.selectByExample类中并没有找到selectByExample方法。
2、解决思路
一般网上会提供几种解决方案:
1、xml文件名与mapper接口名不一致
一致,排除
2、xml文件中namespace与mapper接口的类名不一致
<mapper namespace="com.team.news.mapper.NewsDetailMapper">
可以看到,是一致的,排除
3、xml文件中的方法名和mapper接口方法名不一致
点插件的这个图标,跳转到xml文件中的对应的映射:
<select id="selectByExample" parameterType="com.team.news.entity.NewsDetailExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
'false' as QUERYID,
<include refid="Base_Column_List" />
from news_detail
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
id,parameterType,包括resultMap都检查完毕后,没有问题
4、在主启动类上没有标注@MapperScan或在mapper接口类上没有标注@Mapper
首先声明这两个注解不能同时使用,用一个就够了,查看我的启动类:
@SpringBootApplication
@EnableDiscoveryClient
@EnableTransactionManagement
@MapperScan(value = "com.team.news.mapper")
public class NewsProviderApplication {
public static void main(String[] args) {
SpringApplication.run(NewsProviderApplication.class, args);
}
}
注解也是存在的,并且路径也是正确的
那么,接下来,问题出在哪儿呢?基本上已经把能排除的都排除了。依旧是这个问题。
接下来是我的解决方案,感觉也是最容易被忽略的部分:
5、在pom文件中添加相关资源类打包配置
之后我鼓捣了一下午,猛然在以前的一个项目里看到了pom文件中的一个配置:
<build>
<!--配置相关的资源进行打包-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>
这是将包下的xml资源和resources包下的配置类文件进行对应打包,并将其编译成为.class运行文件
于是我查看了我的mapper工程:
打开这个target=>classes:
在mapper包下果然只看到了两个mapper类,并没有看到对应的xml文件,那么在运行时检测不到对应映射的xml文件,自然找不到对应的方法了。
于是我在该工程下的pom文件中添加:
<build>
<!--配置相关的资源进行打包-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>
再次运行,再打开target=>classes=>mapper:
可以看到所有的xml文件都已经打包完成,再次项目功能正常跑通。