Mybatis反向生成+Swagger自动注释

Java基础

浏览数:115

2020-7-16

AD:资源代下载服务

Mybatis反向生成可以采用mybatis-generator工具
工具的调用方式我选择采用run-with-java 即使用java main函数调用,这种方式的有点是相比maven-plugin调用,省去了jdbc driver包定位的问题,同时方便添加自定义插件,本文就采用了自定义的注释插件来获取数据库字段注释,形成field注释。
同时引入的公用插件有

  • com.github.misterchangray.mybatis.generator.plugin 用于生成swagger注释
  • com.itfsw 该插件包整合了20多个插件,常用的包括lombok支持、批量插入等。

pom.xml

        <!--mybatis反向生成-->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.5</version>
        </dependency>
        <!--反向生成自动swagger注释 -->
        <dependency>
            <groupId>com.github.misterchangray.mybatis.generator.plugins</groupId>
            <artifactId>myBatisGeneratorPlugins</artifactId>
            <version>1.2</version>
        </dependency>
        <!--反向生成增强插件-->
        <dependency>
            <groupId>com.itfsw</groupId>
            <artifactId>mybatis-generator-plugin</artifactId>
            <version>1.3.5</version>
        </dependency>

反向代理规则文件 mybatis-generator.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>

    <context id="testTables" targetRuntime="MyBatis3">
        <!-- 自动为entity生成swagger2文档-->
        <plugin type="mybatis.generator.plugins.GeneratorSwagger2Doc">
            <property name="apiModelAnnotationPackage" value="io.swagger.annotations.ApiModel" />
            <property name="apiModelPropertyAnnotationPackage" value="io.swagger.annotations.ApiModelProperty" />
        </plugin>
        <!-- Example 目标包修改插件 -->
        <plugin type="com.itfsw.mybatis.generator.plugins.ExampleTargetPlugin">
            <property name="targetPackage" value="com.yao.dataforsea_bg.db.dao.example"/>
        </plugin>
        <!-- Lombok插件 -->
        <plugin type="com.itfsw.mybatis.generator.plugins.LombokPlugin">
            <!-- @Data 默认开启,同时插件会对子类自动附加@EqualsAndHashCode(callSuper = true),@ToString(callSuper = true) -->
            <property name="@Data" value="true"/>
            <!-- @Builder 必须在 Lombok 版本 >= 1.18.2 的情况下开启,对存在继承关系的类自动替换成@SuperBuilder -->
            <property name="@Builder" value="false"/>
            <!-- @NoArgsConstructor 和 @AllArgsConstructor 使用规则和Lombok一致 -->
            <property name="@AllArgsConstructor" value="false"/>
            <property name="@NoArgsConstructor" value="false"/>
            <!-- @Getter、@Setter、@Accessors 等使用规则参见官方文档 -->
            <property name="@Accessors(chain = true)" value="false"/>
            <!-- 临时解决IDEA工具对@SuperBuilder的不支持问题,开启后(默认未开启)插件在遇到@SuperBuilder注解时会调用ModelBuilderPlugin来生成相应的builder代码 -->
            <property name="supportSuperBuilderForIdea" value="false"/>
        </plugin>
        <!-- Example Criteria 增强插件 -->
        <plugin type="com.itfsw.mybatis.generator.plugins.ExampleEnhancedPlugin">
            <!-- 是否支持已经过时的andIf方法(推荐使用when代替),默认支持 -->
            <property name="enableAndIf" value="true"/>
        </plugin>
        <!-- Mapper注解插件 -->
        <plugin type="com.itfsw.mybatis.generator.plugins.MapperAnnotationPlugin">
            <!-- @Mapper 默认开启 -->
            <property name="@Mapper" value="true"/>
            <!-- @Repository 默认关闭,开启后解决IDEA工具@Autowired报错 -->
            <property name="@Repository" value="true"/>
        </plugin>

        <!-- 自定义注释生成器 -->

        <commentGenerator type="com.yao.dataforsea_bg.db.plugins.MySQLCommentGenerator">
            <property name="author" value="wpy"/>
            <property name="dateFormat" value="yyyy/MM/dd HH:mm:ss"/>
        </commentGenerator>
        <!--
        <commentGenerator>
            < 是否去除自动生成的注释,true:是,false:否 >
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        -->
        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://188.131.222.102:3306/infocrawler" userId="root"
                        password="wangpengyao11">
        </jdbcConnection>

        <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
           NUMERIC 类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!-- 指定javaBean生成的位置
            targetPackage:生成的类要放的包,真实的包受enableSubPackages属性控制;
            targetProject:目标项目,指定一个存在的目录下,生成的内容会放到指定目录中,如果目录不存在,MBG不会自动建目录
         -->
        <javaModelGenerator targetPackage="com.yao.dataforsea_bg.db.model" targetProject="src/main/java">
            <!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false;如果多个数据库改为true分目录 -->
            <property name="enableSubPackages" value="false"/>
            <!-- 设置是否在getter方法中,对String类型字段调用trim()方法 -->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <!--  指定mapper映射文件生成的位置
           targetPackage、targetProject同javaModelGenerator中作用一样-->
        <sqlMapGenerator targetPackage="mapping" targetProject="src/main/resources">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!-- 指定mapper接口生成的位置
         targetPackage、targetProject同javaModelGenerator中作用一样
         -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.yao.dataforsea_bg.db.dao" targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>

        <!-- 指定数据库表
        domainObjectName:生成的domain类的名字,当表名和domain类的名字有差异时一定要设置,如果不设置,直接使用表名作为domain类的名字;
        可以设置为somepck.domainName,那么会自动把domainName类再放到somepck包里面;
        -->
        <table tableName="downloadfile" domainObjectName="DownloadFile">
            <generatedKey column="id" sqlStatement="select replace(uuid(), '-', '')"></generatedKey>
        </table>
    </context>
</generatorConfiguration>

最后在java类main函数调用
这里需要注意 File 路径默认以idea工程根目录为 初始目录,因此一下代码需要将mybatis-generator.xml放在项目根目录,而非resource目录

package com.yao.dataforsea_bg.db;

/**
 * @Author: wpy
 * @Email: wangpengyao@cnic.cn
 * @Date: 2020-03-31 21:06
 */
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class Generator {
    public static void main( String[] args ) throws Exception {
        List<String> warnings = new ArrayList<>();
        File configFile = new File("./mybatis-generator.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);
    }
}

最后如果仔细看mybatis-generator可以发现,我使用了一个自定义的commentGenerator,它的作用是使用数据库remark作为model类field注释,去除原始生成注释包含的不必要信息,它包括定义接口实现两个类

  1. 父类实现接口
/**
 * @Author: wpy
 * @Email: wangpengyao@cnic.cn
 * @Date: 2020-03-31 21:01
 */
public class EmptyCommentGenerator implements CommentGenerator {

    @Override
    public void addConfigurationProperties(Properties properties) {

    }

    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {

    }

    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable) {

    }

    @Override
    public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {

    }

    @Override
    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {

    }

    @Override
    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean b) {

    }

    @Override
    public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {

    }

    @Override
    public void addGetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {

    }

    @Override
    public void addSetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {

    }

    @Override
    public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {

    }

    @Override
    public void addJavaFileComment(CompilationUnit compilationUnit) {

    }

    @Override
    public void addComment(XmlElement xmlElement) {

    }

    @Override
    public void addRootComment(XmlElement xmlElement) {

    }

}
  1. 子类集成父类
/**
 * @Author: wpy
 * @Email: wangpengyao@cnic.cn
 * @Date: 2020-03-31 20:57
 */
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(" */");
    }
}

作者:wangpengyao