bboyjing's blog

MybatisGenerator插件开发三【Lombok】

如果我们项目中使用了Lombok,那通过自定义插件也能讲其作用于生成的与数据库表映射的Model类上。在这里,我们会同时把表的字段以枚举的形式写到该类中,具体作何使用的话,下一章节会讲到。

修改Model类

直接上代码:

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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
public class LombokPlugin extends PluginAdapter {
private final Collection<Annotations> annotations;
public LombokPlugin() {
annotations = new HashSet<Annotations>(Annotations.values().length);
}
@Override
public boolean validate(List<String> warnings) {
return true;
}
/**
* Intercepts base record class generation
*
* @param topLevelClass
* @param introspectedTable
* @return
*/
@Override
public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass,
IntrospectedTable introspectedTable) {
addDataAnnotation(topLevelClass, true);
addTableColumn(topLevelClass, introspectedTable);
return true;
}
/**
* Intercepts primary key class generation
*
* @param topLevelClass
* @param introspectedTable
* @return
*/
@Override
public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass,
IntrospectedTable introspectedTable) {
addDataAnnotation(topLevelClass, false);
addTableColumn(topLevelClass, introspectedTable);
return true;
}
/**
* Intercepts "record with blob" class generation
*
* @param topLevelClass
* @param introspectedTable
* @return
*/
@Override
public boolean modelRecordWithBLOBsClassGenerated(
TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
addDataAnnotation(topLevelClass, true);
addTableColumn(topLevelClass, introspectedTable);
return true;
}
/**
* Prevents all getters from being generated.
* See SimpleModelGenerator
*
* @param method
* @param topLevelClass
* @param introspectedColumn
* @param introspectedTable
* @param modelClassType
* @return
*/
@Override
public boolean modelGetterMethodGenerated(Method method,
TopLevelClass topLevelClass,
IntrospectedColumn introspectedColumn,
IntrospectedTable introspectedTable,
ModelClassType modelClassType) {
return false;
}
/**
* Prevents all setters from being generated
* See SimpleModelGenerator
*
* @param method
* @param topLevelClass
* @param introspectedColumn
* @param introspectedTable
* @param modelClassType
* @return
*/
@Override
public boolean modelSetterMethodGenerated(Method method,
TopLevelClass topLevelClass,
IntrospectedColumn introspectedColumn,
IntrospectedTable introspectedTable,
ModelClassType modelClassType) {
return false;
}
/**
* Adds the lombok annotations' imports and annotations to the class
*
* @param topLevelClass
*/
private void addDataAnnotation(TopLevelClass topLevelClass, boolean builder) {
for (Annotations annotation : annotations) {
if (!builder && annotation.paramName.equals("builder")) {
continue;
}
topLevelClass.addImportedType(annotation.javaType);
topLevelClass.addAnnotation(annotation.name);
}
}
private void addTableColumn(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
InnerEnum innerEnum = new InnerEnum(new FullyQualifiedJavaType("COLUMNS"));
innerEnum.setVisibility(JavaVisibility.PUBLIC);
innerEnum.setStatic(true);
Field columnField = new Field("column", FullyQualifiedJavaType.getStringInstance());
columnField.setVisibility(JavaVisibility.PRIVATE);
columnField.addAnnotation(Annotations.GETTER.name);
innerEnum.addField(columnField);
introspectedTable.getAllColumns().forEach(introspectedColumn -> {
StringBuilder sb = new StringBuilder();
sb.append(introspectedColumn.getActualColumnName().toUpperCase());
sb.append("(\"");
sb.append(introspectedColumn.getActualColumnName());
sb.append("\")");
innerEnum.addEnumConstant(sb.toString());
});
innerEnum.addAnnotation(Annotations.ALL_ARGS_CONSTRUCTOR.name);
topLevelClass.addInnerEnum(innerEnum);
}
@Override
public void setProperties(Properties properties) {
super.setProperties(properties);
// 要添加到类上的注解
annotations.add(Annotations.DATA);
annotations.add(Annotations.GETTER);
annotations.add(Annotations.BUILDER);
annotations.add(Annotations.ALL_ARGS_CONSTRUCTOR);
for (Entry<Object, Object> entry : properties.entrySet()) {
boolean isEnable = Boolean.parseBoolean(entry.getValue().toString());
if (isEnable) {
String paramName = entry.getKey().toString().trim();
Annotations annotation = Annotations.getValueOf(paramName);
if (annotation != null) {
annotations.add(annotation);
annotations.addAll(Annotations.getDependencies(annotation));
}
}
}
}
private enum Annotations {
GETTER("getter", "@Getter", "lombok.Getter"),
SETTER("setter", "@Setter", "lombok.Setter"),
DATA("data", "@Data", "lombok.Data"),
BUILDER("builder", "@Builder", "lombok.Builder"),
ALL_ARGS_CONSTRUCTOR("allArgsConstructor", "@AllArgsConstructor", "lombok.AllArgsConstructor"),
NO_ARGS_CONSTRUCTOR("noArgsConstructor", "@NoArgsConstructor", "lombok.NoArgsConstructor"),
TO_STRING("toString", "@ToString", "lombok.ToString");
private final String paramName;
private final String name;
private final FullyQualifiedJavaType javaType;
Annotations(String paramName, String name, String className) {
this.paramName = paramName;
this.name = name;
this.javaType = new FullyQualifiedJavaType(className);
}
private static Annotations getValueOf(String paramName) {
for (Annotations annotation : Annotations.values()){
if (String.CASE_INSENSITIVE_ORDER.compare(paramName, annotation.paramName) == 0) {
return annotation;
}
}
return null;
}
private static Collection<Annotations> getDependencies(Annotations annotation) {
if (annotation == ALL_ARGS_CONSTRUCTOR) {
return Collections.singleton(NO_ARGS_CONSTRUCTOR);
} else {
return Collections.emptyList();
}
}
}
}

上述代码的逻辑就是去掉原来的getter、setter,然后在类上添加注解,以及生成表字段枚举。

查看生成文件

将插件添加到项目中,并且运行完MybatisGenerator,我们来查看下生成的相关文件:

Model类:

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
@Data
@AllArgsConstructor
@Getter
@Builder
public class Administrator {
private Long id;
private String mobile;
private String pwd;
private Byte role;
private Integer deleted;
private Long createTime;
private Long updateTime;
@AllArgsConstructor
public enum COLUMNS {
ID("id"),
MOBILE("mobile"),
PWD("pwd"),
ROLE("role"),
DELETED("deleted"),
CREATE_TIME("create_time"),
UPDATE_TIME("update_time");
@Getter
private String column;
}
}

如何使用

使用方式如下:

1
2
3
4
5
6
7
Administrator administrator = Administrator.builder()
.id(globalIdService.nextId())
.mobile(mobile)
.pwd((MD5Util.generate(password)))
.role(role)
.createTime(now)
.updateTime(now).build();

本章节就到这里了。