在大家在数据库字段设计的时候通常会给一些字段规定一些固定值,如订单表中:订单状态字段:会对该字段设置一些特殊的值代表订单状态 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版权协议,转载请附上原文出处链接和本声明。