1. 程式人生 > >Mybatis Generator外掛自動生成xml對映檔案追加與覆蓋的問題

Mybatis Generator外掛自動生成xml對映檔案追加與覆蓋的問題

參考:

mybatis generator 覆蓋xml檔案

使用Mybatis Generator可以快速根據資料庫中已經建立好的表來建立mybatis程式碼,但是一旦資料庫的表結構發生變動,就要重新執行Mybatis Generator外掛。每次執行都會在已經生成的xml後追加一遍所有的內容(包括原來已經生成的程式碼,相當於一個xml中定義了兩次老程式碼)。而po類檔案和java介面檔案會被完全覆蓋。

首先,你可以在每次重新生成之前,手動刪除原來所有的檔案,這樣可以解決追加重複內容的問題。但是如果你要實現一些自定義的資料庫操作方法,那如果每次刪除xml豈不是每次都要重新寫自定義的方法?

那現在我希望的是,既可以不用每次都手動刪除,又可以保留之前自定義的內容。

 

自定義MybatisGenerator外掛解決重複追加內容的問題

在pom.xml引入jar包的依賴

   <!-- mybatis 整合-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.8</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.0</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.7</version>
        </dependency>

然後自定義外掛

public class OverwriteXmlPlugin extends PluginAdapter {
    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    @Override
    public boolean sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) {
        sqlMap.setMergeable(false);
        return super.sqlMapGenerated(sqlMap, introspectedTable);
    }
}

很簡單,只要把Mergeable這個預設是true的值給設定成false就可以了。

將這個類放入到我們的專案中,然後在Gegerator的配置檔案中進行配置(要在context節點下新增)

<!-- 覆蓋xml檔案 -->
<plugin type="com.springapp.mvc.dao.OverwriteXmlPlugin"></plugin>

然後執行generator外掛,報錯

Failed to execute goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.7:generate (default-cli) on project RemoteMonitoringJava: Execution default-cli of goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.7:generate failed: Cannot instantiate object of type com.springapp.mvc.dao.OverwriteXmlPlugin -> [Help 1] 

由於沒有詳細資訊,這時候在maven後新增-e -X再試一下,檢視詳細報錯

mybatis-generator:generate -e -X
Caused by: java.lang.RuntimeException: Cannot instantiate object of type com.springapp.mvc.dao.OverwriteXmlPlugin
	at org.mybatis.generator.internal.ObjectFactory.createInternalObject(ObjectFactory.java:182)
	at org.mybatis.generator.internal.ObjectFactory.createPlugin(ObjectFactory.java:219)
	at org.mybatis.generator.config.Context.generateFiles(Context.java:500)
	at org.mybatis.generator.api.MyBatisGenerator.generate(MyBatisGenerator.java:269)
	at org.mybatis.generator.api.MyBatisGenerator.generate(MyBatisGenerator.java:189)
	at org.mybatis.generator.maven.MyBatisGeneratorMojo.execute(MyBatisGeneratorMojo.java:229)
	at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
	... 26 more

 發現在ObjectFactory中,通過反射生成物件的時候找不到類,看一下原始碼,發現這裡使用

Thread.currentThread().getContextClassLoader()獲取的classloader載入類例項,那我們這個自定義的外掛類也沒有被這個classloader載入啊,所以肯定是無法生成例項的。

檢視一下網上關於自定義外掛的教程。

首先,將剛才自定義的外掛,提取出來,新建一個Java專案,然後將上面寫的依賴也匯入,再將剛才外掛類放入專案中。

使用itellij或是eclipse的功能將專案打成jar包。

使用maven命令將這個jar包釋出到本地的maven庫中。

install:install-file -Dfile=f:/overwritexml.jar -DgroupId=com.ryan -DartifactId=overwritexml -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar

紅色字型根據自己的情況調整。

釋出成功後,在pom.xml配置mybatisGenerator外掛的地方新增對這個jar包的依賴:

 <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.7</version>
                <dependencies>
                    <dependency>
                        <groupId>com.ryan</groupId>
                        <artifactId>overwritexml</artifactId>
                        <version>0.0.1-SNAPSHOT</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>

Dependencies節點下的內容是新加的。

然後再試一次就可以啦,注意下面的這個包名要調整一下,和jar包中的保持一致。但是現在這個十分依賴本地的環境,如果是公司協同開發的話,可以考慮將這個jar包釋出到公司搭建的私有maven倉庫中。

<!-- 覆蓋xml檔案 -->
<plugin type="com.ryan.overwritexml.OverwriteXmlPlugin"></plugin>

解決覆蓋自定義xml中內容的問題

現在每次執行外掛就不用了 每次刪除原有的xml檔案了。但是我自己新定義的方法也被完全覆蓋掉了。

這時候,我一般會使用一個方法(不一定是最合適最正確的,但我自己使用沒什麼問題,可以作為一個參考的方法)。

比如有個使用者表UserTable,通過generator會生成三個檔案,一個mapper對映檔案,UserMapper.xml;一個Po類檔案,User.java;一個Java interface的mapper介面檔案,UserMapper.java.

此時再UserMapper.xml中,mapper節點namespace屬性的值是UserMapper.java的包名+類名。

這時我如果想新加入一個查詢註冊時間在2018年且性別為男性所有使用者的方法,如果還是在UserMapper.xml和UserMapper.java直接加程式碼,下次再用generator生成檔案的時候就會把我們自定義的內容覆蓋掉。

那這時我可以新建一個ExUserMapper.java的介面類,然後定義一個新的方法getUsers(String gender,long startTimestamp,long endTimestamp),然後和UserMapper.java放在相同的包下。

再定義一個ExUserMapper.xml,從UserMapper.xml複製過來resultMap標籤下的內容,然後將namespace的值從UserMapper介面類的全路徑改成ExUserMapper介面類的全路徑,並新增一個id為getUsers的select查詢。

在程式碼裡可以完全使用ExUserMapper.java來生命物件並使用,因為ExUserMapper.java繼承了UserMapper.java,所以UserMapper中提供的基本操作用ExUserMapper也可以獲取到。

唯一的問題就是,如果表結構發生改變了,別忘了把ExUserMapper.xml中的ResultMap同步更新一下。