1:根据sqlId没有找到对应的MapperStatement,有可能是sql语句不存在、或者sqlId的名字和mapper方法中的名字对不上
Exception in thread "main" org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.mybatis.mapper.UserMapper.listUsers at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:196) at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:44) at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:59) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52) at com.sun.proxy.$Proxy0.listUsers(Unknown Source) at com.example.mybatis.TestMybatis.main(TestMybatis.java:27)
从异常的栈信息中,可以看到调用listUsers方法,会调用到代理的invoke方法
List<User> list = userMapper.listUsers("hello105");
调到invoke这个方法:
final MapperMethod mapperMethod = cachedMapperMethod(method);
实例化MapperMethod对象:
private MapperMethod cachedMapperMethod(Method method) {
MapperMethod mapperMethod = methodCache.get(method);
if (mapperMethod == null) {
mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration());
methodCache.put(method, mapperMethod);
}
return mapperMethod;
}
实例化sqlCommand对象:
public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {
this.command = new SqlCommand(config, mapperInterface, method);
this.method = new MethodSignature(config, method);
}
2:mapper.xml 中 ,元素重复的问题,有可能是 resultMap 重复,sql、或者 select等元素重复,也有可能jar包重复了,或者名字重复等
Caused by: java.lang.IllegalArgumentException: Result Maps collection already contains value for com.example.mybatis.mapper.UserMapper.test at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:816) at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:788) at org.apache.ibatis.session.Configuration.addResultMap(Configuration.java:570) at org.apache.ibatis.builder.MapperBuilderAssistant.addResultMap(MapperBuilderAssistant.java:214) at org.apache.ibatis.builder.ResultMapResolver.resolve(ResultMapResolver.java:47) at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:285) at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:252) at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElements(XMLMapperBuilder.java:244) at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:116) ... 7 more
之前的章节我们说过,XMLMapperBuilder是专门用来解析mapper.xml文件,下面我们来从源码的层面分析一下:
从栈信息中可以看出,
找到解析resultMap元素的方法:
resultMap的节点会在resultMapElement方法中解析:
解析后会向configuration中resultMap的缓存中放,由于id重复,所以会抛出异常
抛出异常信息的逻辑:
3:看下面的异常,提示ResultMap缓存中没有userMapper.test的元素
Exception in thread "main" Disconnected from the target VM, address: '127.0.0.1:52974', transport: 'socket' org.apache.ibatis.builder.IncompleteElementException: Could not find result map UserMapper.test at org.apache.ibatis.builder.MapperBuilderAssistant.getStatementResultMaps(MapperBuilderAssistant.java:346) at org.apache.ibatis.builder.MapperBuilderAssistant.addMappedStatement(MapperBuilderAssistant.java:290) at org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parseStatement(MapperAnnotationBuilder.java:317) at org.apache.ibatis.builder.annotation.MethodResolver.resolve(MethodResolver.java:33) at org.apache.ibatis.session.Configuration.buildAllStatements(Configuration.java:738) at org.apache.ibatis.session.Configuration.hasStatement(Configuration.java:702) at org.apache.ibatis.session.Configuration.hasStatement(Configuration.java:697) at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:183) at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:44) at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:59) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52) at com.sun.proxy.$Proxy3.selectUser(Unknown Source) at com.example.mybatis.TestMybatis.main(TestMybatis.java:27) Caused by: java.lang.IllegalArgumentException: Result Maps collection does not contain value for UserMapper.test at org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:832) at org.apache.ibatis.session.Configuration.getResultMap(Configuration.java:584) at org.apache.ibatis.builder.MapperBuilderAssistant.getStatementResultMaps(MapperBuilderAssistant.java:344) ... 12 more
这个异常是因为resultMap的名称对应不上,要么直接写test简称,要么直接全路径名
不能写成其他的名字,下面通过分析源码的形式看一下为什么报错:
这里有个应用命名空间的方法:
如果base是只有带命名空间直接返回,如果包含点,抛异常,如果不带命名空间,则拼接命名空间与方法名,所以resultMap上面的名称要么简写,要么全路径名称。
public String applyCurrentNamespace(String base, boolean isReference) { if (base == null) { return null; } if (isReference) { // is it qualified with any namespace yet? if (base.contains(".")) { return base; } } else { // is it qualified with this namespace yet? if (base.startsWith(currentNamespace + ".")) { return base; } if (base.contains(".")) { throw new BuilderException("Dots are not allowed in element names, please remove it from " + base); } } return currentNamespace + "." + base; }