一、BUG還原
在編寫mybatis通用增刪改查方法時,使用的是Provider動態拼接sql.啓動項目報錯
Caused by: org.apache.ibatis.builder.BuilderException:
Error creating SqlSource for SqlProvider. Method 'deleteById' not found in SqlProvider 'com.*'.
二、分析原因
根據報錯信息查看,爲ProviderSqlSource類的init初始化方法。
public ProviderSqlSource(Configuration config, Object provider) {
String providerMethodName = null;
try {
this.sqlSourceParser = new SqlSourceBuilder(config);
this.providerType = (Class)provider.getClass().getMethod("type").invoke(provider);
providerMethodName = (String)provider.getClass().getMethod("method").invoke(provider);
Method[] arr$ = this.providerType.getMethods();
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; ++i$) {
Method m = arr$[i$];
//providerMethod在賦值時的條件是 :
//1、當前方法與類中所有方法的hash值進行對比
//2、方法的參數必須少於2個
//3、方法的返回值必須爲字符串
if (providerMethodName.equals(m.getName()) && m.getParameterTypes().length < 2 && m.getReturnType() == String.class) {
this.providerMethod = m;
this.providerTakesParameterObject = m.getParameterTypes().length == 1;
}
}
} catch (Exception var8) {
throw new BuilderException("Error creating SqlSource for SqlProvider. Cause: " + var8, var8);
}
//providerMethod這個變量爲空時,拋出異常
if (this.providerMethod == null) {
throw new BuilderException("Error creating SqlSource for SqlProvider. Method '" + providerMethodName + "' not found in SqlProvider '" + this.providerType.getName() + "'.");
}
}
看到這個,就明白了。看我的代碼,傳入兩個參數。這個就是原因所在,我考慮架構師應該是爲了避免重寫問題,所以在這過濾重載問題,而這個設計的。
public String deleteById(String id,String tableName){
SQL sql = new SQL();
sql.UPDATE(tableName);
sql.SET("dr = 1");
sql.WHERE( "id ="+id );
return sql.toString();
}
三、其他
剛開始搜索時,給出的答案是MyProvider動態拼接的方法必須是public修飾,因爲源碼中沒有暴力破解,所以私有方法無法反射導致,小夥伴們也請注意下