MyBatis Generator 自定義生成註釋

最近作項目,ORM 使用的是 MyBatis,爲了偷懶,我天然而然的想到了使用 MyBatis Generator(MBG)來生成數據庫表對應的實體代碼和 Mapper 代碼。因而作了以下的配置(對 MBG 配置不熟悉的同窗能夠參考 Mybatis Generator最完整配置詳解):html

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC
        "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
        
<generatorConfiguration>
    <!-- 指定數據庫驅動的jdbc驅動jar包的位置 -->
    <classPathEntry location="./mysql-connector-java-5.1.40.jar" />

    <context id="mysql" defaultModelType="hierarchical" targetRuntime="MyBatis3Simple" >
        <!-- 生成的 Java 文件的編碼 -->
        <property name="javaFileEncoding" value="UTF-8"/>
        <!-- 格式化 Java 代碼 -->
        <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
        <!-- 格式化 XML 代碼 -->
        <property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>

        <!-- 配置數據庫鏈接 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8" userId="root" password="123456">
        </jdbcConnection>

        <!-- 生成實體的位置 -->
        <javaModelGenerator targetPackage="me.mizhoux.model" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaModelGenerator>

        <!-- 生成 Mapper 接口的位置 -->
        <sqlMapGenerator targetPackage="me.mizhoux.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!-- 生成 Mapper XML 的位置 -->
        <javaClientGenerator targetPackage="me.mizhoux.mapper" type="XMLMAPPER" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!-- 設置數據庫的表名和實體類名 -->
        <table tableName="t_user" domainObjectName="User">
            <!-- generatedKey用於生成生成主鍵的方法 -->
            <generatedKey column="id" sqlStatement="SELECT LAST_INSERT_ID()"/>
        </table>

    </context>

</generatorConfiguration>

數據庫建庫建表的代碼:java

CREATE SCHEMA `db_test` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ;

CREATE TABLE `db_test`.`t_user` (
  `id` INT NOT NULL AUTO_INCREMENT COMMENT '用戶 ID',
  `username` VARCHAR(30) NULL COMMENT '用戶名稱',
  `password` VARCHAR(20) NULL COMMENT '用戶密碼',
  `birthday` DATE NULL COMMENT '用戶生日',
  PRIMARY KEY (`id`),
  UNIQUE INDEX `username_UNIQUE` (`username` ASC)
) COMMENT = '用戶';

開開心心,執行命令,開始生成代碼:mysql

java -jar mybatis-generator-core-1.3.7.jar -configfile generatorConfig.xml -overwritegit

而後查看生成的 Java 實體類:github

生成的 Java 實體

看着這個註釋,讓我有點糾結啊 —— 爲何不是數據庫中每一個字段對應的註釋呢?查找相關資料,得知 MBG 生成的是由 org.mybatis.generator.api.CommentGenerator 來控制的。這是一個接口,MBG 的默認實現類是 org.mybatis.generator.internal.DefaultCommentGenerator。當你在 generatorConfig.xml 中配置了 commentGenerator 標籤,那麼默認狀態下,生成註釋的工做,將由 DefaultCommentGenerator來完成。 因此咱們來查看下這個 DefaultCommentGenerator 的源碼:sql

public class DefaultCommentGenerator implements CommentGenerator {
    // 屬性,即配置在 commentGenerator 標籤以內的 Property 標籤
    private Properties properties;
    // 是否不生成日期
    private boolean suppressDate;
    // 是否不生成註釋
    private boolean suppressAllComments;
    // 是否添加數據庫內的註釋
    private boolean addRemarkComments;
    // 日期的格式
    private SimpleDateFormat dateFormat;

    public DefaultCommentGenerator() {
        super();
        properties = new Properties();
        suppressDate = false;
        suppressAllComments = false;
        addRemarkComments = false;
    }

    @Override
    public void addConfigurationProperties(Properties properties) {
        this.properties.putAll(properties);

        suppressDate = isTrue(properties
                .getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_DATE));
        
        suppressAllComments = isTrue(properties
                .getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));

        addRemarkComments = isTrue(properties
                .getProperty(PropertyRegistry.COMMENT_GENERATOR_ADD_REMARK_COMMENTS));
        
        String dateFormatString = properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_DATE_FORMAT);
        if (StringUtility.stringHasValue(dateFormatString)) {
            dateFormat = new SimpleDateFormat(dateFormatString);
        }
    }
    
    // 其餘代碼
    ...
}

addRemarkComments 這個屬性,看來就是用來生成數據庫註釋用的 —— 好開心,那把它設置爲 true 試試:數據庫

<generatorConfiguration>
    <!-- 指定數據庫驅動的jdbc驅動jar包的位置 -->
    <classPathEntry location="./mysql-connector-java-5.1.40.jar" />
    
    <context id="mysql" defaultModelType="hierarchical" targetRuntime="MyBatis3Simple" >
        <property name="javaFileEncoding" value="UTF-8"/>
        <!-- 其餘 Property -->

        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="addRemarkComments" value="true"/>
        </commentGenerator>
        
        ...
    </context>
</generatorConfiguration>

運行命令:api

java -jar mybatis-generator-core-1.3.7.jar -configfile generatorConfig.xml -overwritemybatis

新生成的 Java 實體

數據庫註釋卻是拿到了,可是生成的一堆其餘信息,看着實在是太扎眼了。查看源碼,發現這些內容已經寫死在 DefaultCommentGenerator 中了,沒有辦法自定義。app

我忽然有一個大膽的想法

本身動手豐衣足食,咱們爲啥不本身寫個類實現 CommentGenerator 接口,而後自定義本身想要的註釋呢。查看 commentGenerator 的 DTD,發現正好 commentGenerator 有個 type 屬性,能夠用來指定本身的註釋實現類:

commentGenerator 的 DTD


觀察 CommentGenerator 接口,發現裏面的方法很是多,不只包含了生成 Java 實體註釋對應的方法,還包括了生成 XML 中註釋的方法。因此咱們先寫一個默認的實現類,實現CommentGenerator 接口,但不作任何操做 —— 由於 DefaultCommentGenerator 本文已經存在了,爲了不混淆,就叫它EmptyCommentGenerator 吧。而後定義咱們本身的註釋類,MySQLCommentGenerator,繼承 EmptyCommentGenerator,重寫咱們須要的方法:

public class MySQLCommentGenerator extends EmptyCommentGenerator {

    private Properties properties;

    public MySQLCommentGenerator() {
        properties = new Properties();
    }

    @Override
    public void addConfigurationProperties(Properties properties) {
        // 獲取自定義的 properties
        this.properties.putAll(properties);
    }

    @Override
    public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        String author = properties.getProperty("author");
        String dateFormat = properties.getProperty("dateFormat", "yyyy-MM-dd");
        SimpleDateFormat dateFormatter = new SimpleDateFormat(dateFormat);

        // 獲取表註釋
        String remarks = introspectedTable.getRemarks();

        topLevelClass.addJavaDocLine("/**");
        topLevelClass.addJavaDocLine(" * " + remarks);
        topLevelClass.addJavaDocLine(" *");
        topLevelClass.addJavaDocLine(" * @author " + author);
        topLevelClass.addJavaDocLine(" * @date " + dateFormatter.format(new Date()));
        topLevelClass.addJavaDocLine(" */");
    }

    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        // 獲取列註釋
        String remarks = introspectedColumn.getRemarks();
        field.addJavaDocLine("/**");
        field.addJavaDocLine(" * " + remarks);
        field.addJavaDocLine(" */");
    }
}

由於咱們如今要使用到咱們本身自定義的 CommentGenerator ,因此咱們 經過代碼的方式來操做 MBG

public class Generator {

    public static void main( String[] args ) throws Exception {
        List<String> warnings = new ArrayList<>();
        File configFile = new File("generatorConfig.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(true);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);
    }

}

而後配置 generatorConfig.xml設置咱們本身的註釋生成器:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC
        "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!-- 指定數據庫驅動的jdbc驅動jar包的位置 -->
    <!-- 再也不須要,由於 jar 包已經在 classpath 中
    <classPathEntry location="./mysql-connector-java-5.1.40.jar" /> 
    -->

    <context id="mysql" defaultModelType="hierarchical" targetRuntime="MyBatis3Simple" >
        ...
        
        <!-- 自定義註釋生成器 -->
        <commentGenerator type="me.mizhoux.mbgcomment.MySQLCommentGenerator">
            <property name="author" value="Michael Chow"/>
            <property name="dateFormat" value="yyyy/MM/dd"/>
        </commentGenerator>
        
        ...
    </context>

</generatorConfiguration>

完整的 Maven 項目在 個人 GitHub。如今,咱們運行主類 Generator,成功生成了數據庫中的註釋:

生成數據庫中的註釋

等等,好像有點不對勁!

我清醒一下

類的註釋怎麼沒有了!

想來應該是 JDBC 鏈接 MySQL 的時候須要添加什麼屬性才能獲取表的註釋,上網查詢,發現是 useInformationSchema,須要將其設置爲 true(看來 MBG 給本身的 DefaultCommentGenerator 開了小竈):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC
        "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <context id="mysql" defaultModelType="hierarchical" targetRuntime="MyBatis3Simple" >
        ...
        
        <!-- 自定義註釋生成器 -->
        <commentGenerator type="me.mizhoux.mbgcomment.MySQLCommentGenerator">
            <property name="author" value="Michael Chow"/>
            <property name="dateFormat" value="yyyy/MM/dd"/>
        </commentGenerator>

        <!-- 配置數據庫鏈接 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8" userId="root" password="123456">
             <!-- 設置 useInformationSchema 屬性爲 true -->
             <property name="useInformationSchema" value="true" />
        </jdbcConnection>
        
        ...
    </context>
</generatorConfiguration>

而後再次運行主類 Generator

最終的生成結果

成功的生成了類註釋和字段註釋~


我這裏並無處理註釋是多行文本的狀況 —— 留給有興趣的讀者吧~
小項目地址:https://github.com/mizhoux/mbg-comment

相關文章
相關標籤/搜索