0%

MyBatis 生成器的表注释

MyBatis是流行的持久化框架,通过抽象底层的JDBC代码,在类对象和数据库列之间自动映射SQL的参数和结果,以SQL为映射的间接层,实现SQL映射器。MyBatis Generator (MBG) 是一个Mybatis的代码生成器,内省数据库的表,然后自动生成映射表的实体类,并生成CRUD(插入,查询,更新,删除)操作的样板代码。MyBatis,之前所在的公司在用,生成器也在用。虽然生成器大大提供了开发效率,但生成的代码可读性比较低,尤其是自动生成的实体类,如下:

1
2
3
4
5
/**
* This field was generated by MyBatis Generator. This field corresponds to the database column author.book_id
* @mbggenerated Tue Jan 19 13:37:24 CST 2016
*/
private Integer bookId;

这些自动生成注释,没有实质性信息,其实真正有用的是,设计表时,该字段的用途,即表字段的注释。

addRemarkComments选项

庆幸的是,MyBatis生成器在版本1.3.3中添加了,addRemarkComments选项 [github],可以在生成的实体类中附带表字段的注释。addRemarkComments官方文档的介绍 [doc]:

This property is used to specify whether MBG will include table and column remarks from db table in the generated comments. The property supports these values:

  • false: This is the default value When the property is false or unspecified, all generated comments will not include table and column remarks from db table when the element was generated.
  • true: When the property is true, table and columns remarks from db table will be added to the generated comments.

Warning: If suppressAllComments option is true, this option will be ignored.

使用方法很简单,只需将MyBatis生成器的配置文件中的commentGenerator节点修改为:

1
2
3
<commentGenerator>
<property name="addRemarkComments" value="true" />
</commentGenerator>

自定义注释生成器类

通过addRemarkComments选项生成的实体类的注释不够精简。于是笔者参考MyBatis的默认的注释生成器DefaultCommentGenerator[github],对其进行改造成如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package com.test.mbg;

import java.util.Date;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.JavaElement;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.config.MergeConstants;
import org.mybatis.generator.internal.DefaultCommentGenerator;
import org.mybatis.generator.internal.util.StringUtility;

/**
* 官方类似的功能见,在版本1.3.3中添加的 addRemarkComments <br>
* http://www.mybatis.org/generator/configreference/commentGenerator.html <br>
* https://github.com/mybatis/generator/issues/23
*
* @see DefaultCommentGenerator#addRemarkComments
*/
public class RemarksCommentGenerator extends DefaultCommentGenerator {

@Override
public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
topLevelClass.addJavaDocLine("/**");

String remarks = introspectedTable.getRemarks();
if (StringUtility.stringHasValue(remarks)) {
String[] remarkLines = remarks.split(System.getProperty("line.separator"));
for (String remarkLine : remarkLines) {
topLevelClass.addJavaDocLine(" * " + remarkLine);
}
}

topLevelClass.addJavaDocLine(" * ");
StringBuilder sb = new StringBuilder();
sb.append(" * ");
sb.append(introspectedTable.getFullyQualifiedTable());
topLevelClass.addJavaDocLine(sb.toString());
topLevelClass.addJavaDocLine(" *");
addJavadocTag(topLevelClass, false);
topLevelClass.addJavaDocLine(" */");
}

public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
field.addJavaDocLine("/**");

String remarks = introspectedColumn.getRemarks();
if (StringUtility.stringHasValue(remarks)) {
String[] remarkLines = remarks.split(System.getProperty("line.separator"));
for (String remarkLine : remarkLines) {
field.addJavaDocLine(" * " + remarkLine);
}
}

field.addJavaDocLine(" *");
StringBuilder sb = new StringBuilder();
sb.append(" * ");
sb.append(introspectedTable.getFullyQualifiedTable());
sb.append('.');
sb.append(introspectedColumn.getActualColumnName());
field.addJavaDocLine(sb.toString());
field.addJavaDocLine(" *");
addJavadocTag(field, false);
field.addJavaDocLine(" */");
}

public void addFieldComment(Field field, IntrospectedTable introspectedTable) {
field.addJavaDocLine("/**");
addJavadocTag(field, false);
field.addJavaDocLine(" */");
}

public void addGetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
method.addJavaDocLine("/**");
addJavadocTag(method, false);
method.addJavaDocLine(" */");
}

public void addSetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
method.addJavaDocLine("/**");
addJavadocTag(method, false);
method.addJavaDocLine(" */");
}

protected void addJavadocTag(JavaElement javaElement, boolean markAsDoNotDelete) {
StringBuilder sb = new StringBuilder();
sb.append(" * ");
sb.append(MergeConstants.NEW_ELEMENT_TAG);
if (markAsDoNotDelete) {
sb.append(" do_not_delete_during_merge"); //$NON-NLS-1$
}
String s = getDateString();
if (s != null) {
sb.append(' ');
sb.append(s);
}
javaElement.addJavaDocLine(sb.toString());
}

protected String getDateString() {
return DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
}
}

MyBatis的配置文件修改为:

1
2
<commentGenerator type="com.test.mbg.RemarksCommentGenerator">
</commentGenerator>

运行MyBatis生成器

改用自定义的RemarksCommentGenerator后,运行MyBatis插件可能会报错。需要使用Java来运行MyBatis生成器,代码如下 [doc]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.test.mbg;

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

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;

/**
* 使用Java运行 MyBatis Generator
* http://www.mybatis.org/generator/running/runningWithJava.html
*/
public class MyBatisGen {

public static void main(String[] args) throws Exception {
String fileName = "F:/code/mybatis-generator.xml";
File configFile = new File(fileName);
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
}