1. 程式人生 > >Mybatis-generator修改原始碼實現自定義方法,返回List物件(二)

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。