使用MybatisPlus时发生异常:Invalid bound statement (not found)
先上结论:yml文件没有将原来的mybatis的配置更名为mybatis-plus
异常:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): XXMapper.getCapitalTypeListAll
源码探寻:
首先断点打在调用mapper方法的地方
List<HashMap<String, Object>> capitalTypeData = configMapper.getCapitalTypeListAll();
继续走,进入MybatisMapperMethod.java类
public SqlCommand(Configuration configuration, Class<?> mapperInterface, Method method) { //methodName就是调用的方法名 getCapitalTypeListAll final String methodName = method.getName(); //declaringClass就是 Mapper接口类 final Class<?> declaringClass = method.getDeclaringClass(); //问题出在这里 返回为空:原因是没有找到该接口类 MappedStatement ms = resolveMappedStatement(mapperInterface, methodName, declaringClass, configuration); if (ms == null) { if (method.getAnnotation(Flush.class) != null) { name = null; type = SqlCommandType.FLUSH; } else { 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); } } }
private MappedStatement resolveMappedStatement(Class<?> mapperInterface, String methodName, Class<?> declaringClass, Configuration configuration) { //XXMapper.xxMethod String statementId = mapperInterface.getName() + "." + methodName; //configuration有一个大集合,缓存了所有的Mapper及所有的方法 如图1.1 if (configuration.hasStatement(statementId)) { return configuration.getMappedStatement(statementId); } else if (mapperInterface.equals(declaringClass)) { return null; } for (Class<?> superInterface : mapperInterface.getInterfaces()) { if (declaringClass.isAssignableFrom(superInterface)) { MappedStatement ms = resolveMappedStatement(superInterface, methodName, declaringClass, configuration); if (ms != null) { return ms; } } } return null; } }
protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>("Mapped Statements collection") .conflictMessageProducer((savedValue, targetValue) -> ". please check " + savedValue.getResource() + " and " + targetValue.getResource());
public boolean hasStatement(String statementName) { return hasStatement(statementName, true); } public boolean hasStatement(String statementName, boolean validateIncompleteStatements) { if (validateIncompleteStatements) { buildAllStatements(); } return mappedStatements.containsKey(statementName); }
问题就在这里 ,mappedStatements没有工程的mapper,原因就是没有扫描到,即定位到扫描时配置问题!
mybatis -> mybatis-plus
问题解决!
图1.1