基于MybatisGenerator一键生成工程代码,重复性工作交给它准没错

1,185 阅读5分钟

现在大多数的项目都是分多层结构,经典的如遵循MVC规范(Model-View-Controller),如果按照DDD领域模型设计可能会划分更多层,每一层需要创建多个类似模式的类文件和内容,包括类名、注释、属性、方法等,基于数据模型生成代码的插件和工具有很多,比如mybatis-plus、mybatis-generator、mybatisx等,当然市面上也有许多代码自动生成的产品,这些代码生成方式大部分都是生成固定文件结构,但是大多公司一般有自己的一套框架结构或者重新设计的分层结构,这个时候就需要自定义代码生成文件格式,包括生成文件位置和内容格式,今天为大家带来基于mybatis-generator插件的方式实现自定义代码结构,更好的适配现有代码工程。

基础配置

基于插件基本功能生成的代码,包括Do.javaExample.javaMapper.javaMapper.xml文件,其中生成内容没有对应的注释信息,或者配置生成的配置信息不够人性化,基本无用。

插件配置

<plugins>
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    <plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.4.2</version>
        <dependencies>
            <dependency>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-core</artifactId>
                <version>1.4.2</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.32</version>
            </dependency>
        </dependencies>
        <configuration>
            <!-- 输出详细信息 -->
            <verbose>true</verbose>
            <!-- 覆盖生成的类文件 -->
            <overwrite>true</overwrite>
            <!-- 定义配置文件 -->
            <configurationFile>${basedir}/src/main/resources/generator-configuration.xml</configurationFile>
        </configuration>
    </plugin>
</plugins>

配置Maven插件,可以比较容易的触发生成代码。

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!-- 设置生成的文件适用于哪个Mybatis 版本 -->
    <context id="default" targetRuntime="MyBatis3">
        <!-- 生成RowBounds方法 -->
        <plugin type="org.mybatis.generator.plugins.RowBoundsPlugin"/>
        <!-- 覆盖XML Mapper文件,POM文件中配置的是Class文件覆盖 -->
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>

        <!-- 旨在创建class时,对注释进行控制 -->
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <!-- 是否去除自动生成的注释 true:是 false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!-- jdbc的数据库连接 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/code_gen?useSSL=false"
                        userId="root"
                        password="123456"/>
        <!-- 非必须,类型处理器,在数据库类型和java类型之间的转换控制,默认情况下数据库中的decimal,bigint在Java对应是sql下的BigDecimal类 -->
        <javaTypeResolver>
            <!-- 使用常用的基本类型代替sql包下的引用类型 -->
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!-- 生成的实体类所在的包 -->
        <javaModelGenerator targetPackage="com.example.codegen.domain" targetProject="src/main/java">
            <!-- 是否允许子包 -->
            <property name="enableSubPackages" value="true"/>
            <!-- 是否清理从数据库中查询出的字符串左右两边的空白字符 -->
            <property name="trimStrings" value="false"/>
        </javaModelGenerator>
        <!-- 生成的mapper xml文件的包和位置 -->
        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
            <!-- 针对数据库的一个配置,是否把schema作为字包名 -->
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>
        <!-- 生成的mapper class文件的包和位置 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.codegen.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>

        <!-- 表配置 -->
        <table tableName="system_users" domainObjectName="SystemUsersDo"/>
    </context>
</generatorConfiguration>

配置注释信息写的比较清楚,这里给出部分配置信息,能够满足大部分需求,如有特殊需求可以参考 官方文档

效果展示

生成代码总览 具体生成内容介于文章内容就不做展示,大家可以实际配置生成。

准备工作

进入正题配置我们的自定义插件配置,基于MybatisGenerator提供的上下文信息可以方便的获取到元数据信息,自定义插件有两种解决方案:

  1. 在项目工程中定义插件,执行生成代码可以动态加载对应的插件;
  2. 基于MybatisGenerator核心包修改,不侵入项目工程,可以方便的分享给其他人使用;

当然,本篇文章主要介绍基于MybatisGenerator核心包修改的方式,简单在GitHub上边搜索mybatis-generator-core发现魔改项目还挺多,接下来实际进行操作。

拉取核心包

可以从GitHub直接拉取魔改的仓库,或者直接下载源码解压,我这里直接从仓库中找到源码并解压,mybatis-generator-core-1.4.2-sources。

导入工程

  • 将源码包移动到/src/main/java中;
  • 从/META-INF/maven/org.mybatis.generator/mybatis-generator-core中将pom.xml文件复制一份出来放到根目录下并删除部分内容;
  • 修改坐标,groupId或者artifactId都是可以的;
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.local.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.0.0</version>
    <name>mybatis-generator-core</name>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.6</version>
            <scope>provided</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.20.0</version>
            <scope>provided</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
            <scope>provided</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.10.13</version>
            <scope>provided</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>5.9.2</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.9.2</version>
        </dependency>
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.24.2</version>
        </dependency>
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>2.7.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.github.javaparser</groupId>
            <artifactId>javaparser-core</artifactId>
            <version>3.25.0</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib</artifactId>
            <version>1.8.10</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

其中依赖版本从parent获取,配置完成后移除parent,配置完成后注意执行mvn clean install操作,将包install到仓库中

工程依赖自定义插件

依赖自定义的工程包,groupId和artifactId可以自行修改,我这里未变更,仅修改版本号为1.0.0,执行生成代码查看效果,我这里执行无任何变化,需要注意的是一定需要修改坐标,不然可能遇到执行出现null的情况,目测是插件执行过程中验证了某些信息。

自定义插件

说了一堆前置条件,终于到了文章的重点,自定义插件逻辑实现,本篇文章主要介绍定制化Mapper.java、实体注释优化、Service.java生成逻辑,可以参考生成更多内容,如Controller.java、Manager.java等等,生成逻辑都是相似的几乎可以CV CV CV,一个分层结构插件可能存在比较多的上下文,为了方便按照层拆分插件数量。

  • JavaMapperPlugin插件:主要定制化基础插件功能生成的Do.java、Mapper.java文件;
  • ServicePluginc插件:生成Model.javaConvertor.javaService.javaServiceImpl.java文件;

添加配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!-- 设置生成的文件适用于哪个Mybatis 版本 -->
    <context id="default" targetRuntime="MyBatis3">
        <!-- 自定义全局属性,根据实际情况进行修改 -->
        <property name="author" value="reboot"/>
        <property name="baseProject" value="/Users/xx/Codes/IdeaProjects/Demos/code-gen"/>

        <!-- 生成RowBounds方法 -->
        <plugin type="org.mybatis.generator.plugins.RowBoundsPlugin"/>
        <!-- 覆盖XML Mapper文件,POM文件中配置的是Class文件覆盖 -->
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>
        <!-- 自定义插件,Mapper生成、扩展添加注释、使用通用接口 -->
        <plugin type="org.mybatis.generator.plugins.custom.JavaMapperPlugin"/>
        <!-- 自定义插件,Service生成 -->
        <plugin type="org.mybatis.generator.plugins.custom.ServicePlugin"/>

        <!-- 旨在创建class时,对注释进行控制 -->
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <!-- 是否去除自动生成的注释 true:是 false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!-- jdbc的数据库连接 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/code_gen?useSSL=false"
                        userId="root"
                        password="123456"/>
        <!-- 非必须,类型处理器,在数据库类型和java类型之间的转换控制,默认情况下数据库中的decimal,bigint在Java对应是sql下的BigDecimal类 -->
        <javaTypeResolver>
            <!-- 使用常用的基本类型代替sql包下的引用类型 -->
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!-- 生成的实体类所在的包 -->
        <javaModelGenerator targetPackage="com.example.codegen.domain" targetProject="src/main/java">
            <!-- 是否允许子包 -->
            <property name="enableSubPackages" value="true"/>
            <!-- 是否清理从数据库中查询出的字符串左右两边的空白字符 -->
            <property name="trimStrings" value="false"/>
        </javaModelGenerator>
        <!-- 生成的mapper xml文件的包和位置 -->
        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
            <!-- 针对数据库的一个配置,是否把schema作为字包名 -->
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>
        <!-- 生成的mapper class文件的包和位置 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.codegen.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>

        <!-- 表配置 -->
        <table tableName="system_users" domainObjectName="SystemUsersDo">
            <property name="comment" value="系统用户"/>
            <generatedKey column="id" sqlStatement="Mysql" identity="true"/>
        </table>
    </context>
</generatorConfiguration>

修改点如下:

<!-- 自定义全局属性,根据实际情况进行修改 -->
<property name="author" value="reboot"/>
<property name="baseProject" value="/Users/xx/Codes/IdeaProjects/Demos/code-gen"/>

<!-- 自定义插件,Mapper生成、扩展添加注释、使用通用接口 -->
<plugin type="org.mybatis.generator.plugins.custom.JavaMapperPlugin"/>
<!-- 自定义插件,Service生成 -->
<plugin type="org.mybatis.generator.plugins.custom.ServicePlugin"/>

<!-- 表配置,其中comment属性为自定义添加 -->
<table tableName="system_users" domainObjectName="SystemUsersDo">
    <property name="comment" value="系统用户"/>
    <generatedKey column="id" sqlStatement="Mysql" identity="true"/>
</table>

JavaMapperPlugin插件

package org.mybatis.generator.plugins.custom;

import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.DefaultJavaFormatter;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.TopLevelClass;

import java.util.ArrayList;
import java.util.List;

/**
 * JavaMapper插件
 *
 * @author reboot
 */
public class JavaMapperPlugin extends PluginAdapter {

    private List<String> warnings;
    private String       tableComment;
    private String       author;
    private String       baseProject;

    private static final String MAPPER_BASE    = "/src/main/java";
    private static final String MAPPER_PACKAGE = "com.example.codegen.mapper";

    @Override
    public boolean validate(List<String> warnings) {
        this.warnings = warnings;
        return true;
    }

    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
        tableComment = introspectedTable.getTableConfigurationProperty("comment");
        author = introspectedTable.getContext().getProperty("author");
        baseProject = introspectedTable.getContext().getProperty("baseProject");

        List<GeneratedJavaFile> javaFiles = new ArrayList<>();
        // DO
        javaFiles.add(generateDoFile(introspectedTable));
        // Mapper
        javaFiles.add(generateMapperFile(introspectedTable));

        return javaFiles;
    }

    /**
     * 生成DO文件
     *
     * @param introspectedTable 表信息
     * @return {@link GeneratedJavaFile}
     */
    private GeneratedJavaFile generateDoFile(IntrospectedTable introspectedTable) {
        String fullDoName = introspectedTable.getBaseRecordType();
        String doName = PluginUtils.getClassName(fullDoName);

        PluginUtils.fileExistCheck(fullDoName, baseProject + MAPPER_BASE, warnings);

        TopLevelClass doTopLevelClass = PluginUtils.generateEntity(introspectedTable, this.context, fullDoName,
                PluginUtils.classDoc(tableComment + "数据模型", doName, author));
        return new GeneratedJavaFile(doTopLevelClass, baseProject + MAPPER_BASE, new DefaultJavaFormatter());
    }

    /**
     * 生成Mapper文件
     *
     * @param introspectedTable 表信息
     * @return {@link GeneratedJavaFile}
     */
    private GeneratedJavaFile generateMapperFile(IntrospectedTable introspectedTable) {
        String fullDoName = introspectedTable.getBaseRecordType();
        String doName = PluginUtils.getClassName(fullDoName);
        String mapperName = doName + "Mapper";
        String fullMapperName = MAPPER_PACKAGE + "." + mapperName;
        String exampleName = doName + "Example";
        String fullExampleName = fullDoName + "Example";

        PluginUtils.fileExistCheck(fullMapperName, baseProject + MAPPER_BASE, warnings);

        Interface baseMapperInterface = new Interface(new FullyQualifiedJavaType(fullMapperName));
        baseMapperInterface.addFileCommentLine(PluginUtils.fileComment());
        baseMapperInterface.setVisibility(JavaVisibility.PUBLIC);
        baseMapperInterface.addJavaDocLine(PluginUtils.classDoc(tableComment + "Mapper", mapperName, author));
        baseMapperInterface.addSuperInterface(new FullyQualifiedJavaType("BaseMapper<" + doName + "," + exampleName + ">"));

        baseMapperInterface.addImportedType(new FullyQualifiedJavaType("com.example.codegen.mapper.BaseMapper"));
        baseMapperInterface.addImportedType(new FullyQualifiedJavaType(fullDoName));
        baseMapperInterface.addImportedType(new FullyQualifiedJavaType(fullExampleName));

        return new GeneratedJavaFile(baseMapperInterface, baseProject + MAPPER_BASE, new DefaultJavaFormatter());
    }
}

ServicePluginc插件

package org.mybatis.generator.plugins.custom;

import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.DefaultJavaFormatter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.internal.util.JavaBeansUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * Service插件
 *
 * @author reboot
 */
public class ServicePlugin extends PluginAdapter {

    private List<String> warnings;
    private String       tableComment;
    private String       author;
    private String       baseProject;

    private static final String SERVICE_BASE    = "/src/main/java";
    private static final String SERVICE_PACKAGE = "com.example.codegen.service";
    private static final String MAPPER_PACKAGE  = "com.example.codegen.mapper";

    @Override
    public boolean validate(List<String> warnings) {
        this.warnings = warnings;
        return true;
    }

    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
        tableComment = introspectedTable.getTableConfigurationProperty("comment");
        author = introspectedTable.getContext().getProperty("author");
        baseProject = introspectedTable.getContext().getProperty("baseProject");

        List<GeneratedJavaFile> javaFiles = new ArrayList<>();
        // Service
        javaFiles.add(generateServiceFile(introspectedTable));

        return javaFiles;
    }

    /**
     * 生成Service文件
     *
     * @param introspectedTable 表信息
     * @return {@link GeneratedJavaFile}
     */
    private GeneratedJavaFile generateServiceFile(IntrospectedTable introspectedTable) {
        String fullDoName = introspectedTable.getBaseRecordType();
        String doName = PluginUtils.getClassName(fullDoName);
        String serviceName = doName.replace("Do", "Service");
        String fullServiceName = SERVICE_PACKAGE + "." + serviceName;
        String mapperName = doName + "Mapper";
        String fullMapperName = MAPPER_PACKAGE + "." + mapperName;

        PluginUtils.fileExistCheck(fullServiceName, baseProject + SERVICE_PACKAGE, warnings);

        TopLevelClass serviceTopLevelClass = new TopLevelClass(fullServiceName);
        serviceTopLevelClass.addFileCommentLine(PluginUtils.fileComment());
        serviceTopLevelClass.setVisibility(JavaVisibility.PUBLIC);
        serviceTopLevelClass.addJavaDocLine(PluginUtils.classDoc(tableComment + "领域服务实现", serviceName, author));
        serviceTopLevelClass.addAnnotation("@Component");
        Field mapperField = new Field(JavaBeansUtil.getValidPropertyName(mapperName), new FullyQualifiedJavaType(mapperName));
        mapperField.setVisibility(JavaVisibility.PUBLIC);
        mapperField.addAnnotation("@Autowired");
        serviceTopLevelClass.addField(mapperField);

        serviceTopLevelClass.addImportedType("org.springframework.stereotype.Component");
        serviceTopLevelClass.addImportedType("org.springframework.beans.factory.annotation.Autowired");
        serviceTopLevelClass.addImportedType(fullMapperName);

        return new GeneratedJavaFile(serviceTopLevelClass, baseProject + SERVICE_BASE, new DefaultJavaFormatter());
    }
}

抽取通用工具

package org.mybatis.generator.plugins.custom;

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.JavaVisibility;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.internal.util.JavaBeansUtil;

import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 插件工具类
 *
 * @author reboot
 */
public class PluginUtils {

    /**
     * 文件存在性检查
     *
     * @param fullName 全名
     * @param basePath 基本路径
     * @param warnings 警告
     */
    public static void fileExistCheck(String fullName, String basePath, List<String> warnings) {
        String path = String.join(File.separator, basePath, fullName.replace(".", File.separator), ".java");
        if (new File(path).exists()) {
            warnings.add("java file" + fullName + " already exists in " + basePath + " and will be overridden.");
        }
    }

    /**
     * 获取类名
     *
     * @param recordType 记录类型
     * @return {@link String}
     */
    public static String getClassName(String recordType) {
        return recordType.substring(recordType.lastIndexOf(".") + 1);
    }

    /**
     * 文件注释,自行实现
     *
     * @return {@link String}
     */
    public static String fileComment() {
        return "/* 文件头 2023 */";
    }

    /**
     * 类注释
     *
     * @param remark    备注
     * @param className 类名
     * @param author    作者
     * @return {@link String}
     */
    public static String classDoc(String remark, String className, String author) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm");
        StringBuilder javaDoc = new StringBuilder();
        javaDoc.append("/**\n");
        javaDoc.append(" * " + remark + "\n");
        javaDoc.append(" *\n");
        javaDoc.append(" * @author " + author + "\n");
        javaDoc.append(" * @version " + className + ".java, v0.1 " + LocalDateTime.now().format(dateTimeFormatter) + " " + author + "\n");
        javaDoc.append(" */");
        return javaDoc.toString();
    }

    /**
     * 属性注释
     *
     * @param remark 备注
     * @return {@link String}
     */
    public static String fieldDoc(String remark) {
        StringBuilder fieldDoc = new StringBuilder();
        fieldDoc.append("/**\n");
        fieldDoc.append("\t * " + remark);
        fieldDoc.append("\n");
        fieldDoc.append("\t */");
        return fieldDoc.toString();
    }

    /**
     * 生成实体
     *
     * @param introspectedTable 表信息
     * @param context           上下文
     * @param fullName          全限定名
     * @param javaDoc           java注释
     * @return {@link TopLevelClass}
     */
    public static TopLevelClass generateEntity(IntrospectedTable introspectedTable, Context context, String fullName, String javaDoc) {
        TopLevelClass topLevelClass = new TopLevelClass(fullName);
        topLevelClass.addFileCommentLine(fileComment());
        topLevelClass.setVisibility(JavaVisibility.PUBLIC);
        topLevelClass.addAnnotation("@Data");
        topLevelClass.addImportedType("lombok.Data");
        topLevelClass.addJavaDocLine(javaDoc);
        for (IntrospectedColumn introspectedColumn : introspectedTable.getAllColumns()) {
            Field field = JavaBeansUtil.getJavaBeansField(introspectedColumn, context, introspectedTable);
            field.addJavaDocLine(fieldDoc(introspectedColumn.getRemarks()));
            topLevelClass.addField(field);
            topLevelClass.addImportedType(field.getType());
        }
        return topLevelClass;
    }
}

验证效果

SystemUsersDo.java

SystemUsersDoMapper.java

SystemUsersService.java

Service这里仅仅举个例子,我写的插件生成内容比较简单,可以根据实际情况生成。

总结

虽说不建议重复造轮子,但是轮子没有那么好,就只好基于轮子造轮子了,上边的写法可能不是最好的,但是能满足项目工程总体框架结构,一般的后台系统生成基本的CRUD功能还是非常方便的,基于这种方式几乎项目中相同模式的代码都可以生成,不要让基础的功能浪费大量时间。