Mybatis-generator修改原始碼實現自定義方法,返回List物件(二)
上一篇我們講了如何獲取Mybatis-generator的原始碼和建立工程,以及通過main方法來生成XML、實體類、mapper檔案,這一篇我們來講通過修改程式碼來為mapper新增一個方法
2、組合原始碼中的示例,實現Dao(Mapper)層新增一個方法
結合網上的教程研究後,我知道了這兩個包,分別是生成dao(mapper)檔案和XML檔案的JAVA類,那麼我們先研究javamapper這個包
這個包裡的 JavaMapperGenerator.java,有一個方法 getCompilationUnits,它是控制生成的dao檔案具體有哪些方法的,程式碼就是
但是並不是所有的方法都生成,具體邏輯我還沒有去研究過
然後我檢視這個包下面的叫做 elements包,它裡頭有很多的類,其實就是截圖中addXXX方法需要呼叫到的類,這些方法會例項化elements包下的類,並使用它組合出方法。
開啟SelectByPrimaryKeyMethodGenerator 這個類,這就是根據ID查詢資料的方法,
主要介紹這個類裡的addInterfaceElements方法,它將我們寫方法時候的作用範圍,返回型別,方法名,引數,以及import,都專門設計了物件,下面我將註釋寫出來
我們跟蹤紅色箭頭的方法,發現它返回了一個列舉列表中的某個值,這個列舉在org.mybatis.generator.api.IntrospectedTable類裡頭,而且列舉裡的值,正好於elements包下面的java檔案對應,還發現了這些資料是用在了這個類的get和set方法裡,跟蹤set方法,發現它被本類的calculateXmlAttributes方法呼叫,並在裡頭設定了我們所看到的方法名:
到這裡,我們就可以想到,新增一個方法,首先要建立在elements包裡頭建立一個類,然後在這個列舉裡頭新增資料,實現get和set方法,然後在JavaMapperGenerator類中去add,那麼現在我們就可以嘗試著建立一個方法了。
第一步.先在elements拷貝一個類,模板就用SelectByPrimaryKeyMethodGenerator ,類名改為SelectByObjectMethodGenerator。
第二步.在org.mybatis.generator.apiIntrospectedTable類的InternalAttribute列舉中新增一條資料
ATTR_SELECT_BY_ObJECT//自定義方法
寫上它的get和set方法
public String getSelectByObject() {
return internalAttributes
.get(InternalAttribute.ATTR_SELECT_BY_ObJECT);
}
public void setSelectByObject(String s) {
internalAttributes.put(
InternalAttribute.ATTR_SELECT_BY_ObJECT, s);
}
並在calculateXmlAttributes方法裡呼叫set方法,傳入我們想要的方法名
第三步. 在JavaMapperGenerator類中新增一個方法
//自定義方法
protected void addSelectByObjectMethod(Interface interfaze) {
if (introspectedTable.getRules().generateSelectByPrimaryKey()) {
AbstractJavaMapperMethodGenerator methodGenerator = new SelectByObjectMethodGenerator(false);
initializeAndExecuteGenerator(methodGenerator, interfaze);
}
}
注意這裡的 if 條件判斷,理論上我不應該使用 introspectedTable.getRules().generateSelectByPrimaryKey() 這個判斷的,但是如果要去Rule介面新建一個方法的話,它的實現類也很多,修改起來就很麻煩,那麼我們這裡暫時不改,但是能用,有興趣的同學,可以自己去深入研究一下,歡迎在部落格下面留言,我們一起探討。
然後在這個類的getCompilationUnits 方法中呼叫這個方法
完成這三步,就可以在dao層新建一個方法了,但是我們實際引用的模板依然是SelectByPrimaryKeyMethodGenerator 類,所以我們需要修改我們新建的SelectByObjectMethodGenerator類中的 addInterfaceElements 方法
首先我想到的是,SelectByPrimaryKey返回的是一個數據庫示例物件,但是我的需求裡是要返回一個List,自己不會寫這樣的返回型別,怎麼辦,看看有沒有寫好的例子,正好在SelectAllMethodGenerator類裡頭,它所生產的方法,正好是List型別的,抄抄抄
@Override
public void addInterfaceElements(Interface interfaze) {
//先建立import物件
Set<FullyQualifiedJavaType> importedTypes = new TreeSet<FullyQualifiedJavaType>();
//新增Lsit的包
importedTypes.add(FullyQualifiedJavaType.getNewListInstance());
//建立方法物件
Method method = new Method();
//設定該方法為public
method.setVisibility(JavaVisibility.PUBLIC);
//設定返回型別是List
FullyQualifiedJavaType returnType = FullyQualifiedJavaType
.getNewListInstance();
FullyQualifiedJavaType listType;
//設定List的型別是實體類的物件
listType = new FullyQualifiedJavaType(
introspectedTable.getBaseRecordType());
importedTypes.add(listType);
//返回型別物件設定為List
returnType.addTypeArgument(listType);
//方法物件設定返回型別物件
method.setReturnType(returnType);
//設定方法名稱為我們在IntrospectedTable類中初始化的 “selectByObject”
method.setName(introspectedTable.getSelectByObject());
//設定引數型別是物件
FullyQualifiedJavaType parameterType;
if (isSimple) {
parameterType = new FullyQualifiedJavaType(
introspectedTable.getBaseRecordType());
} else {
parameterType = introspectedTable.getRules()
.calculateAllFieldsClass();
}
//import引數型別物件
importedTypes.add(parameterType);
//為方法新增引數,變數名稱record
method.addParameter(new Parameter(parameterType, "record")); //$NON-NLS-1$
//
addMapperAnnotations(interfaze, method);
context.getCommentGenerator().addGeneralMethodComment(method,
introspectedTable);
if (context.getPlugins().clientSelectByPrimaryKeyMethodGenerated(
method, interfaze, introspectedTable)) {
interfaze.addImportedTypes(importedTypes);
interfaze.addMethod(method);
}
}
這是修改完後的程式碼,註釋僅僅寫了一部分,也挺拗口的,朋友們可以刪了按照自己的,其他的你們可以自己深入研究
第四步. 執行MyTestRun的main方法,就可以看到在dao層的方法中加了一個方法(最好把原來的dao層的java檔案刪掉,因為我不確定是否覆蓋)
理論上就可以看到下圖中的新增方法了
下一篇我們會介紹,如何在xml檔案中,新增這個方法的sql。