扩展mybatis generator 插件根据字段注释生成常量及整合Lombok

        在大家在数据库字段设计的时候通常会给一些字段规定一些固定值,如订单表中:订单状态字段:会对该字段设置一些特殊的值代表订单状态 1: 订单创建初始化状态 2:订单待支付状态 3:订单支付成功状态 4:订单支付失败状态 5: 订单取消状态等等。

       我们会将这些字段说写入到字段注释说明中,在代码中使用的时候根据不同的值进行不同业务处理。这些字段特定值,我们通常会这个写成常量,为了提高代码的可读性,可维护性。但既然已经使用generator自动生成了DB实体类,mapper接口,怎么还需要去手写常量呢?

        Plugin能够用来在MyBatis Generator生成Java和XML文件过程中修改或者添加内容;Plugin必须实现org.mybatis.generator.api.Plugin接口,在这个接口中提供了非常多的方法,所以,MBG提供了一个适配器org.mybatis.generator.api.PluginAdapter,一般情况下只需要继承这个适配器即可;

因此我们通过继承 PluginAdapter进行

自定义常量plugin扩展。

       思路如下:

      1、在数据库上在字段加上注释;  

      2、注释中会有该字段的含义说明,需要有特定的模板;

      3、根据这模板对常量进行解析;

      4、将解析出来的常量值,在DB实体类中生成常量。

我定义是模板是json字符串类型   

模板>>   注释{'常量后缀1':'值#描述','常量后缀2':'值#描述’}

核心代码如下

  @Override
  public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        this.comment(field, topLevelClass, introspectedColumn,introspectedTable);
        return true;
   } 
  private void comment(JavaElement element,TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,IntrospectedTable introspectedTable) {
        element.getJavaDocLines().clear();
        element.addJavaDocLine("/**");
        //获取列字段注解
        String remark = introspectedColumn.getRemarks();
        if (remark != null && remark.length() > 1) {
            element.addJavaDocLine(" * " + remark);
            element.addJavaDocLine(" *");
        }
        element.addJavaDocLine(" * Column:    " + introspectedColumn.getActualColumnName());
        element.addJavaDocLine(" * Length:    " + introspectedColumn.getLength());
        element.addJavaDocLine(" * DefaultValue:  " + (StringUtility.stringHasValue(introspectedColumn.getDefaultValue()) ? introspectedColumn.getDefaultValue() : "无默认值"));
        element.addJavaDocLine(" * Nullable:  " + introspectedColumn.isNullable());
        boolean autoIncrement = introspectedColumn.isAutoIncrement();
        if (autoIncrement){
            element.addJavaDocLine(" * AutoIncrement:  true");
        }
        element.addJavaDocLine(" */");
        if (this.makeConstant) {
            System.out.println("start constant " + introspectedColumn.getActualColumnName());
            if (StringUtility.stringHasValue(remark) && remark.contains(JSON_PREFIX) && remark.contains(JSON_SUFFIX)) {
                //截取常量字符串
                String commentJson = remark.substring(remark.indexOf(JSON_PREFIX), remark.lastIndexOf(JSON_SUFFIX) + 1);
                try {
                    LinkedHashMap<String, String> commentMap = JsonUtil.fromJson(LinkedHashMap.class, commentJson);
                    commentMap.forEach((key, value) -> {
                        Field field = new Field();
                        //常量字段属性名 以列字段名+_+json key 值为字段名
                     field.setName(introspectedColumn.getActualColumnName().toUpperCase() + "_" + key.toUpperCase());     
                        field.setStatic(true);
                        field.setFinal(true);
                        //设置常量字段类型与列字段一致
                        field.setType(introspectedColumn.getFullyQualifiedJavaType());
                        //常量字段属性描述
                        String desc = "";
                        //常量字段属性值
                        String constant = "";
                        if (value.contains(SEPARATION)) {
                            String[] split = value.split(SEPARATION);
                            constant = split[0];
                            desc = split[1];
                        } else {
                            constant = value;
                        }
                        field.setInitializationString(constant);
                        field.setVisibility(JavaVisibility.PUBLIC);
                        field.addJavaDocLine("/**");
                        field.addJavaDocLine("* " + introspectedColumn.getActualColumnName() + ":" + desc);
                        field.addJavaDocLine("*/");
                        if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3_DSQL) {
                            context.getCommentGenerator().addFieldAnnotation(field, introspectedTable,
                                    topLevelClass.getImportedTypes());
                        } else {
                            context.getCommentGenerator().addFieldComment(field, introspectedTable);
                        }
                        //将常量加入BD实体类
                        topLevelClass.addField(field);
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

 整合lombok:

   private FullyQualifiedJavaType dataAnnotation;

    public LombokPlugin() {
        dataAnnotation = new FullyQualifiedJavaType("lombok.Data");
    }
    
    @Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass,
                                                 IntrospectedTable introspectedTable) {
        addDataAnnotation(topLevelClass);
        return true;
    }

      @Override
    public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass,
                                                 IntrospectedTable introspectedTable) {
        addDataAnnotation(topLevelClass);
        return true;
    }

    /**
     * Adds the @Data lombok import and annotation to the class
     *
     * @param topLevelClass
     */
    protected void addDataAnnotation(TopLevelClass topLevelClass) {
        topLevelClass.addImportedType(dataAnnotation);
        topLevelClass.addAnnotation("@Data");
    }

最后在 generator.xml 中使用自定义插件

        <!-- 整合lombok-->
        <plugin type="center.gingko.mybatis.generator.plugins.LombokPlugin" >
            <property name="hasLombok" value="true"/>
        </plugin>
        <!--自定义注释插件-->
        <plugin type="center.gingko.mybatis.generator.plugins.CommentPlugin">
            <!--开启根据注释生成常量,需把常量字段定义为json-->
            <!--模板规则-->
            <!--注释{'常量后缀1':'值#描述','常量后缀2':'值#描述’}-->
            <property name="makeConstant" value="true"/>
            <!--作者-->
            <property name="author" value="lambert" />
        </plugin>

运行后效果如下:

sql ddl:

CREATE TABLE `t_sync` (
  `id` varchar(16) NOT NULL,
  `user_number` varchar(50) DEFAULT NULL,
  `state` int(1) DEFAULT NULL COMMENT '同步状态{''init'':''0#未开始'',''processing'':''1#处理中'',''finish'':''2#完成''}',
  `sync_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='同步状态表';
package center.gingko.data.model;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

/**
 * @describe: 
 * @create: 2019-12-10 17:31:12
 * @table: T_SYNC
 * @author: lambert
 */
@Table(name = "T_SYNC")
@Data
public class TSync implements Serializable {
    /**
     * Column:    id
     * Length:    16
     * DefaultValue:  无默认值
     * Nullable:  false
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private String id;

    /**
     * Column:    user_number
     * Length:    50
     * DefaultValue:  无默认值
     * Nullable:  true
     */
    @Column(name = "user_number")
    private String userNumber;

    /**
    * state:未开始
    */
    public static final Integer STATE_INIT = 0;

    /**
    * state:处理中
    */
    public static final Integer STATE_PROCESSING = 1;

    /**
    * state:完成
    */
    public static final Integer STATE_FINISH = 2;

    /**
     * 同步状态{'init':'0#未开始','processing':'1#处理中','finish':'2#完成'}
     *
     * Column:    state
     * Length:    10
     * DefaultValue:  无默认值
     * Nullable:  true
     */
    private Integer state;

    /**
     * Column:    sync_time
     * Length:    19
     * DefaultValue:  无默认值
     * Nullable:  true
     */
    @Column(name = "sync_time")
    private Date syncTime;


    private static final long serialVersionUID = 1L;
}

初次发帖,请大家多多指教


版权声明:本文为qq_22746887原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。