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; }