问题描述
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.dao.mysql.Mapper.select
at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235)
at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:53)
at org.apache.ibatis.binding.MapperProxy.lambda$cachedInvoker$0(MapperProxy.java:108)
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
at org.apache.ibatis.util.MapUtil.computeIfAbsent(MapUtil.java:35)
at org.apache.ibatis.binding.MapperProxy.cachedInvoker(MapperProxy.java:95)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86)
at com.sun.proxy.$Proxy103.selectEquipmentState(Unknown Source)
报错信息如上所示,给人第一反应就是mapper文件绑定关系不对,但是会有多种情况导致这样的报错,需要我们耐心且细心的一步步排查。其实服务在启动的时候也已经给过警告信息了,只是一般不报错的情况下,我们也没有去细看,知道后来才发现,如图:
WARN 4192 --- [ restartedMain] o.m.s.mapper.ClassPathMapperScanner : Skipping MapperFactoryBean with name 'Mapper' and 'com.dao.mysql.Mapper' mapperInterface. Bean already defined with the same name!
WARN 4192 --- [ restartedMain] o.m.s.mapper.ClassPathMapperScanner : No MyBatis mapper was found in '[com.dao.mysql]' package. Please check your configuration.
第一种方案:
检查对应的xml文件是否映射到mapper文件上,在xml文件的namespace上,按住ctrl键不放,鼠标移动到对应的mapper文件名上是可以点击过去的;或者可以用mybatis组件是可以直接跳转,如图所示:
第二种方案:
检查mapper接口中的方法名和mapper.xml中的id标签是否一致
第三种方案:
如果说mapper映射没有问题,那么就有可能的配置问题。先检查yml或者properties配置文件里的mapper-locations
# 指定路径
mybatis:
mapper-locations: classpath*:mapper/*.xml
# 多文件路径
## 第一种写法
mybatis:
mapper-locations: classpath*:mapper/*/*.xml
## 第二种写法
mybatis:
mapper-locations: classpath*:mapper/a/*.xml,mapper/b/*.xml
# 多层文件多路径写法
mybatis:
mapper-locations: classpath*:mapper/**/*.xml
然后检查数据源配置的路径对不对
第四种方案:
检查你的启动类是否增加了mapper包扫描注解,检查包扫描路径的正确性
@SpringBootApplication
@EnableSwagger2
@MapperScan(basePackages = "com.dao")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
如果你在数据源配置文件里就已经加了包扫描,启动类里就不需要再加mapper包扫描,参照第三种方案。
第四种方案:
有时候我们会在创建多层文件夹的时候会图方便,一次性创建完,如:mapper.aaa.vvv
看图吧,更直观:
然后看不到有任何的异常,但是这只是一个文件夹,而不是层级文件夹,会导致mapper文件路径跟xml文件路径不一致,正确创建方式应该是:mapper/aaa/vvv
idea有一个很好的排查方式,点击项目右上角的齿轮,取消缩减中间包,如图:
**>
效果如下:
第五种方案:
检查target文件下mapper文件是否映射上,因为我们知道所有的文件都是经过编译器编译成class文件来被机器来读取,如果不对可以重新编译一下
第六种方案:
这种的由单数据源改配多数据源的情况下,所有的配置映射关系都没有问题。请求第一个数据源接口返回正常,请求第二个数据源所有接口都报未绑定这个错。
排查第一个数据源配置文件里读取的mapper文件路径应该到存放对应mapper文件那一层级,否则可能读取了其他数据源的mapper文件,你在调用接口的时候就会默认到第一数据源里面去找,很显然是不会匹配上的。
xml配置读取也一样,都做区分避免出问题
总结
遇到问题还是多思考,即使是平时很常见的问题,也有可能让你找好久才找到原因。一定要根据报错去找问题,
能导致问题就那么几个点,一定要细心一点点去排查,就能发现蛛丝马迹。