看到的錯誤信息一模一樣都是這樣的:Method threw 'org.apache.ibatis.binding.BindingException' exception.Invalid bound statement (not found): **.dao.**Dao.selectjava
1.考慮返回值類型是否不匹配,一頓修改,@Results 也使用到。 最終無果。sql
2.開始各類百度,先申明本人使用的方式註解方式, 並不是最經常使用的xml方式。 百度內容大都雷同,檢查包名,類名,方法名 是否映射。無果。apache
3.因爲 mybatis 報的錯誤,不是很明確。 無奈只能debug 源碼。mybatis
4. 查看更爲詳細的異常日誌app
1 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.sankuai.meituan.banma.thrift.activity.admin.dao.CouponPossessDao.selectUnusedPageNum 2 at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:214) ~[mybatis-3.4.0.jar:3.4.0] 3 at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:48) ~[mybatis-3.4.0.jar:3.4.0] 4 at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:59) ~[mybatis-3.4.0.jar:3.4.0] 5 at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52) ~[mybatis-3.4.0.jar:3.4.0] 6 at com.sun.proxy.$Proxy96.selectUnusedPageNum(Unknown Source) ~[na:na] 7 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131] 8 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131] 9 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131] 10 at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131] 11 at com.dianping.zebra.dao.AsyncMapperProxy.invoke(AsyncMapperProxy.java:64) ~[zebra-dao-0.2.4.jar:na] 12 at com.sun.proxy.$Proxy96.selectUnusedPageNum(Unknown Source) ~[na:na]
第二行是重點。點擊查看代碼。ide
1 public SqlCommand(Configuration configuration, Class<?> mapperInterface, Method method) { 2 String statementName = mapperInterface.getName() + "." + method.getName(); 3 MappedStatement ms = null; 4 if(configuration.hasStatement(statementName)) { //正常的邏輯都會進入該 if 邏輯,而後獲得ms。 該方法未進入該邏輯。不到是該方法初始化時,就失敗了。 5 ms = configuration.getMappedStatement(statementName); 6 } else if(!mapperInterface.equals(method.getDeclaringClass())) { 7 String parentStatementName = method.getDeclaringClass().getName() + "." + method.getName(); 8 if(configuration.hasStatement(parentStatementName)) { 9 ms = configuration.getMappedStatement(parentStatementName); 10 } 11 } 12 13 if(ms == null) { 14 if(method.getAnnotation(Flush.class) == null) { 15 throw new BindingException("Invalid bound statement (not found): " + statementName); //該行即爲拋出的異常日誌 16 } 17 18 this.name = null; 19 this.type = SqlCommandType.FLUSH; 20 } else { 21 this.name = ms.getId(); 22 this.type = ms.getSqlCommandType(); 23 if(this.type == SqlCommandType.UNKNOWN) { 24 throw new BindingException("Unknown execution method for: " + this.name); 25 } 26 } 27 28 }
下面開始追蹤初始化的代碼塊。ui
1 public class ZebraMapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> { 2 private Class<T> mapperInterface; 3 private boolean addToConfig = true; 4 5 public ZebraMapperFactoryBean() { 6 } 7 8 public void setMapperInterface(Class<T> mapperInterface) { 9 this.mapperInterface = mapperInterface; 10 } 11 12 public void setAddToConfig(boolean addToConfig) { 13 this.addToConfig = addToConfig; 14 } 15 16 protected void checkDaoConfig() { 17 super.checkDaoConfig(); 18 Assert.notNull(this.mapperInterface, "Property 'mapperInterface' is required"); 19 Configuration configuration = this.getSqlSession().getConfiguration(); 20 if(this.addToConfig && !configuration.hasMapper(this.mapperInterface)) { 21 try { 22 configuration.addMapper(this.mapperInterface);//下面跟進該方法查詢具體的報錯行 23 } catch (Throwable var6) { 24 this.logger.error("Error while adding the mapper '" + this.mapperInterface + "' to configuration.", var6); // 初始化時,執行到這裏其實已經報錯了。可是沒影響啓動 25 throw new IllegalArgumentException(var6); 26 } finally { 27 ErrorContext.instance().reset(); 28 } 29 } 30 31 }
public class MapperAnnotationBuilder {
private SqlSource getSqlSourceFromAnnotations(Method method, Class<?> parameterType, LanguageDriver languageDriver) {
try {
Class<? extends Annotation> sqlAnnotationType = this.getSqlAnnotationType(method);
Class<? extends Annotation> sqlProviderAnnotationType = this.getSqlProviderAnnotationType(method);
Annotation sqlProviderAnnotation;
if(sqlAnnotationType != null) {
if(sqlProviderAnnotationType != null) {
throw new BindingException("You cannot supply both a static SQL and SqlProvider to method named " + method.getName());
} else {
sqlProviderAnnotation = method.getAnnotation(sqlAnnotationType);
String[] strings = (String[])((String[])sqlProviderAnnotation.getClass().getMethod("value", new Class[0]).invoke(sqlProviderAnnotation, new Object[0]));
return this.buildSqlSourceFromStrings(strings, parameterType, languageDriver);
}
} else if(sqlProviderAnnotationType != null) {
sqlProviderAnnotation = method.getAnnotation(sqlProviderAnnotationType);
return new ProviderSqlSource(this.assistant.getConfiguration(), sqlProviderAnnotation);
} else {
return null;
}
} catch (Exception var8) {
throw new BuilderException("Could not find value method on SQL annotation. Cause: " + var8, var8); //最初的報錯的位置
}
}
這裏就能夠找到具體的初始化失敗的方法了。this
5.至此找到了,正確的解決方案。spa
6.由此得出幾個結論。1.mybatis 報警的確是很不明確。 2.出現問題,優先仍是優先考慮排除法。一段代碼一段代碼檢查。 debug