转载

MybatisGenerator插件开发三【Lombok】

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

修改Model类

直接上代码:

public class LombokPluginextends 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类:

@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;
    }
}

如何使用

使用方式如下:

Administrator administrator = Administrator.builder()
    .id(globalIdService.nextId())
    .mobile(mobile)
    .pwd((MD5Util.generate(password)))
    .role(role) 
    .createTime(now)
    .updateTime(now).build();

本章节就到这里了。

原文  http://bboyjing.github.io/2019/03/14/MybatisGenerator插件开发三【Lombok】/
正文到此结束
Loading...