【福利,掘金周边】【Spring Boot 快速入门】十一、Spring Boot集成AutoGenerator代码生成器

5,044 阅读11分钟

【福利,本文评论用户将有机会获得掘金新版徽章 1 枚】

前言

  XDM大家好,金秋时节,又与大家见面了。在8月份进行了满勤日更,已经“肝胆欲裂”了。8月底出来新的活动:一次免费申请掘金周边礼物的机会。抱着试试看的想法,提交了申请,争取为广大掘友申请福利。作者有幸获得了首批试行阶段的名额,感谢长期以来各位读者对小阿杰的认可,也感谢掘金提供本次机会,使作者与读者更好的互动。

  活动链接如下:请查收|你有一次免费申请掘金周边礼物的机会

  收到的系统站内信:

图片.png   官网公布的名单。在收到申请周边活动成功之后的,也进行了充分的技术选题,在能输出技术知识的同时,又能充分调动读者的积极互动性。经过慎重思考之后,选择了写代码生成以及大家对代码生成器在项目中使用的一些思考,针对这些问题展开讨论。 图片.png   好了开始正题,本次为大家介绍的代码生成器是MyBatis-Plus中的AutoGenerator。

初识 AutoGenerator。

  相信使用过的代码生成器小伙伴对此都感觉很爽,刷刷刷的基础代码就已经开发完成了。在Java开始过程中有一款经常使用的代码生成器AutoGenerator。AutoGenerator是MyBatis-Plus的代码生成器,通过AutoGenerator可以快速生成 Entity、Mapper、Mapper XML、Service、Controller等各个模块的代码,极大的提升了开发效率,减少了基础代码重复编写的工作。

快速开始

添加依赖

  MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖:本文针对Java开发者,使用Maven引入依赖包信息。


        <!--    mybatis-plus    -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.0</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.29</version>
        </dependency>
        <!--    mybatis-plus    -->

基本配置

  在使用AutoGenerator代码生成器中,需要对相关参数进行配置,以便生成相关代码。主要配置包含:数据源配置、数据库表配置、包名配置、模板配置、全局策略配置、注入配置等。下面具体介绍各个配置的参数及其作用。

数据源配置

  数据源配置DataSourceConfig,其默认值:null,通过该配置,指定需要生成代码的具体数据库。

参数类型描述备注
dbQuery数据库信息查询类默认由 dbType 类型决定选择对应数据库内置实现
dbType数据库类型该类内置了常用的数据库类型【必须】
schemaName数据库 schema name例如 PostgreSQL 可指定为 public
typeConvert类型转换默认由 dbType 类型决定选择对应数据库内置实现
url驱动连接的URL数据库的链接地址
driverName驱动名称例如:com.mysql.cj.jdbc.Driver
username数据库连接用户名数据库连接用户名
password数据库连接密码数据库连接密码

数据库表配置

  数据库表配置StrategyConfig,其默认值:null,通过该配置,可指定需要生成哪些表或者排除哪些表。

参数类型描述备注与默认值
isCapitalMode是否大写命名false
skipView是否跳过视图false
naming数据库表映射到实体的命名策略
columnNaming数据库表字段映射到实体的命名策略, 未指定按照 naming 执行null
tablePrefix表前缀
fieldPrefix字段前缀
superEntityClass自定义继承的Entity类全称,带包名
superEntityColumns自定义基础的Entity类,公共字段
superMapperClass自定义继承的Mapper类全称,带包名String SUPER_MAPPER_CLASS = "com.baomidou.mybatisplus.core.mapper.BaseMapper";
superServiceClass自定义继承的Service类全称,带包名String SUPER_SERVICE_CLASS = "com.baomidou.mybatisplus.extension.service.IService";
superServiceImplClass自定义继承的ServiceImpl类全称,带包名
superControllerClass自定义继承的Controller类全称,带包名
enableSqlFilter默认激活进行sql模糊表名匹配,关闭之后likeTable与notLikeTable将失,include和exclude将使用内存过滤,如果有sql语法兼容性问题的话,请手动设置为false
include需要包含的表名,当enableSqlFilter为false时,允许正则表达式(与exclude二选一配置null
likeTable自3.3.0起,模糊匹配表名(与notLikeTable二选一配置)likeTable
exclude需要排除的表名,当enableSqlFilter为false时,允许正则表达式null
notLikeTable自3.3.0起,模糊排除表名null
entityColumnConstant【实体】是否生成字段常量(默认 false)false
chainMode【实体】是否为构建者模型(默认 false)3.3.2开始原来版本是 entityBuilderModel
entityLombokModel【实体】是否为lombok模型(默认 false)3.3.2以下版本默认生成了链式模型,3.3.2以后,
entityBooleanColumnRemoveIsPrefixBoolean类型字段是否移除is前缀(默认 false)false
restControllerStyle生成 @RestController 控制器false
controllerMappingHyphenStyle驼峰转连字符false
entityTableFieldAnnotationEnable是否生成实体时,生成字段注解false
versionFieldName乐观锁属性名称
logicDeleteFieldName逻辑删除属性名称is_del
tableFillList表填充字段

包名配置

  包名配置PackageConfig,其默认值:null,通过该配置,指定生成代码的包路径。

参数类型描述默认值
parent父包名。如果为空,将下面子包名必须写全部, 否则就只需写子包名com.baomidou
moduleName父包模块名null
entityEntity包名entity
serviceService包名service
serviceImplService Impl包名service.impl
mapperMappermapper
xmlMapper XML包名mapper.xml
controllerController包名controller
pathInfo路径配置信息

模板配置

  模板配置TemplateConfig,其默认值:null,可自定义代码生成的模板,实现个性化操作。

参数类型描述备注
entityJava 实体类模板/templates/entity.java
entityKtKotin 实体类模板/templates/entity.kt
serviceService 类模板/templates/service.java
serviceImplService impl 实现类模板/templates/serviceImpl.java
mappermapper 模板/templates/mapper.java
xmlmapper xml 模板/templates/mapper.xml
controllercontroller 控制器模板/templates/controller.java

全局策略配置

  全局策略配置GlobalConfig,其默认值:null。

参数类型描述备注
outputDir生成文件的输出目录默认值:D 盘根目录
fileOverride是否覆盖已有文件默认值:false
open是否打开输出目录默认值:true
enableCache是否在xml中添加二级缓存配置默认值:`false
author开发人员默认值:null
kotlin开启 Kotlin 模式默认值:false
swagger2开启 swagger2 模式默认值:false
activeRecord开启 ActiveRecord 模式默认值:false
baseResultMap开启 BaseResultMap默认值:false
baseColumnList开启 baseColumnList默认值:false
dateType时间类型对应策略默认值:TIME_PACK
entityName实体命名方式默认值:null 例如:%sEntity 生成 UserEntity
mapperNamemapper 命名方式默认值:null 例如:%sDao 生成 UserDao
xmlNameMapper xml 命名方式默认值:null 例如:%sDao 生成 UserDao.xml
serviceNameservice 命名方式默认值:null 例如:%sBusiness 生成 UserBusiness
serviceImplNameservice impl 命名方式默认值:null 例如:%sBusinessImpl 生成 UserBusinessImpl
controllerNamecontroller 命名方式默认值:null 例如:%sAction 生成 UserAction
idType指定生成的主键的ID类型默认值:null

注入配置

  注入配置InjectionConfig,其默认值:null,通过该配置,可注入自定义参数等操作以实现个性化操作。

参数类型描述备注
map自定义返回配置 Map 对象该对象可以传递到模板引擎通过 cfg.xxx 引用
fileOutConfigList自定义输出文件配置 FileOutConfig 指定模板文件、输出文件达到自定义文件生成目的
fileCreate自定义判断是否创建文件实现 IFileCreate 接口
initMap注入自定义 Map 对象(注意需要setMap放进去)

  通过上述介绍的配置信息,MyBatis-Plus 的AutoGenerator代码生成器提供了大量的自定义参数,能够满足绝大部分人的使用需求。下面针对上述配置进行编写代码。其实就是针对DataSourceConfig、StrategyConfig、PackageConfig、TemplateConfig、GlobalConfig、InjectionConfig这些实体类赋值即可。

示例

设置常量

 /**
     * 需要生成的表名
     * */
    private static final String[] TABLE_NAMES = new String[]{"z_seo"};
    /**
     * 文件路径
     * */
    public static final String PROJECT_PATH = "E:\\bootproject\\BootDemo\\";
    //
    /**
     * 项目名
     * */
    public static final String PROJECT_NAME = "18BootAutoGenerator";
    /**
     * 模块名称
     * */
    public static final String MODULE_NAME ="";

    /**
     * 数据源配置
     * */
    public static final String DATA_SOURCE_URL ="jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior" +
            "=convertToNull";
    public static final String DATA_SOURCE_USERNAME ="test";
    public static final String DATA_SOURCE_PASSWORD ="123456";
    public static final String DATA_SOURCE_DRIVERNAME ="com.mysql.cj.jdbc.Driver";

初始化代码生成器

     /**
     * @MethodName: main
     * @Description: 代码生成器
     * @Return: 
     * @Author: JavaZhan @公众号:Java全栈架构师
     * @Date: 2021/9/8
     **/
    public static void main(String[] args) {
            // 代码生成器
            AutoGenerator autoGenerator = new AutoGenerator();
            autoGenerator.setDataSource(getDataSourceConfigInfo());
            autoGenerator.setGlobalConfig(getGlobalConfigInfo());
            autoGenerator.setPackageInfo(getPackageConfigInfo());
            autoGenerator.setStrategy(getStrategyConfigInfo(TABLE_NAMES));
            autoGenerator.setTemplate(new TemplateConfig().setXml(null));
            autoGenerator.setTemplateEngine(new FreemarkerTemplateEngine());
            autoGenerator.setCfg(getInjectionConfigInfo());
            autoGenerator.execute();
        }

数据源配置

     /**
     * @MethodName: getDataSourceConfigInfo
     * @Description: 数据源配置
     * @Return: DataSourceConfig
     * @Author: JavaZhan @公众号:Java全栈架构师
     * @Date: 2021/9/8
     **/
     public static DataSourceConfig getDataSourceConfigInfo() {
            DataSourceConfig dataSourceConfig = new DataSourceConfig();
            dataSourceConfig.setUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull");
            dataSourceConfig.setUsername("test");
            dataSourceConfig.setPassword("123456");
            dataSourceConfig.setDbType(DbType.MYSQL);
            dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
            return dataSourceConfig;
     }

全局配置

     /**
     * @MethodName: getGlobalConfigInfo
     * @Description: 全局配置
     * @Return: GlobalConfig
     * @Author: JavaZhan @公众号:Java全栈架构师
     * @Date: 2021/9/8
     **/
    public static GlobalConfig getGlobalConfigInfo() {
            // 全局配置
            GlobalConfig globalConfig = new GlobalConfig();
    //        String projectPath = System.getProperty("user.dir");
            globalConfig.setOutputDir(PROJECT_PATH + PROJECT_NAME + "/src/main/java/");
            globalConfig.setAuthor("JavaZhan");
            globalConfig.setOpen(false);
            globalConfig.setSwagger2(true);
            globalConfig.setBaseColumnList(true);
            globalConfig.setBaseResultMap(true);
            globalConfig.setActiveRecord(false);
            globalConfig.setFileOverride(true);
            globalConfig.setServiceName("%sService");
            return globalConfig;
        }

包配置

     /**
     * @MethodName: getPackageConfigInfo
     * @Description: 包配置
     * @Return: PackageConfig
     * @Author: JavaZhan @公众号:Java全栈架构师
     * @Date: 2021/9/8
     **/
     public static PackageConfig getPackageConfigInfo() {
            PackageConfig packageConfig = new PackageConfig();
            packageConfig.setParent("com.example.demo");
            packageConfig.setModuleName("test");
            packageConfig.setEntity("module");
            return packageConfig;
        }

策略配置

    /**
     * @MethodName: getStrategyConfigInfo
     * @Description: 策略配置
     * @Return: StrategyConfig
     * @Author: JavaZhan @公众号:Java全栈架构师
     * @Date: 2021/9/8
     **/
    public static StrategyConfig getStrategyConfigInfo(String... tableNames) {
            StrategyConfig strategyConfigInfo = new StrategyConfig();
            strategyConfigInfo.setCapitalMode(true);
            strategyConfigInfo.setNaming(NamingStrategy.underline_to_camel);
            //下划线转驼峰命名
            strategyConfigInfo.setColumnNaming(NamingStrategy.underline_to_camel);
            //需要生成的的表名,多个表名传数组
            strategyConfigInfo.setInclude(tableNames);
            //设置逻辑删除字段
            strategyConfigInfo.setLogicDeleteFieldName("data_state");
            //使用lombok
            strategyConfigInfo.setEntityLombokModel(true);
            //设置表格前缀
            strategyConfigInfo.setTablePrefix("");
            //rest风格
            strategyConfigInfo.setRestControllerStyle(true);

            return strategyConfigInfo;
        }

抽象的对外接口

     /**
     * @MethodName: getInjectionConfigInfo
     * @Description: 抽象的对外接口
     * @Return: InjectionConfig
     * @Author: JavaZhan @公众号:Java全栈架构师
     * @Date: 2021/9/8
     **/
    public static InjectionConfig getInjectionConfigInfo(){
            InjectionConfig injectionConfig = new InjectionConfig() {
                @Override
                public void initMap() {
                }
            };
            List<FileOutConfig> focList = new ArrayList<FileOutConfig>();
            focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
                @Override
                public String outputFile(TableInfo tableInfo) {
                    // 输出xml
                    return PROJECT_PATH + PROJECT_NAME + "/src/main/resources/mapper/" + MODULE_NAME
                            + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
                }
            });
            injectionConfig.setFileOutConfigList(focList);
            return injectionConfig;
        }

执行

  在项目中执行初始化main方法,出现如下图中日志,包含module、service、impl、mapper、xml等相关文件。 图片.png

  如下图,生成的自动生成的文件相关文件目录结构,把我们需要的基本文件都已经生成了。 图片.png   如下图中是我们生成的实体对象信息,其中包含了lombok和swagger2的相关注解,如果不需要这些,可以在GlobalConfig全局配置文件中进行配置。

图片.png   好了,本文基于Spring Boot集成AutoGenerator代码生成器的相关功能已经介绍完了,并针对配置进行了Demo演示。大家可以根据项目中具体的需要,进行更加详实的参数配置,以满足个性化的需求。

思考(欢迎留言评论交流)

1、使用AutoGenerator代码生成器有哪些弊端?

2、大家还有哪些常用的代码生成器推荐,分享给大家?

3、关于使用代码生成器,在使用过程中都遇到过哪些奇葩的事情?

4、针对代码生成器你持什么态度?

5、在使用AutoGenerator代码生成器中遇到哪些问题,大家一起讨论学习。

欢迎大家积极交流评论。

福利

  本文参加的是:请查收|你有一次免费申请掘金周边礼物的机会 ,在所有评论用户中,将产生2位幸运的评论用户,将获得掘金官方提供的掘金新版徽章 2 枚

评论区抽奖要求(官方要求):

  • 截止到 9月10日,如果评论区超过 10 人互动(不含作者本人),作者可以以自己的名义抽奖送出掘金新版徽章 2 枚(掘金官方承担)。
  • 截止到 9月10日,如果评论区超过 10 人互动(不含作者本人),评论数超过 20 条(含作者本人),作者本人额外获得一份掘金周边礼物。
  • 评论区热度最高(评论人数+条数综合数据)TOP 1-5:新版徽章1套 或 掘金新版IPT恤1件

获奖条件

  热评幸运用户 如果本文评论达到掘金活动的要求,将从热评区用户中抽取一位幸运读者赠送掘金新版徽章 1 枚。如无热评用户,将转为评论幸运用户。

  评论幸运用户 如果本文评论达到掘金活动的要求,将所有评论区用户中抽取一位幸运读者赠送掘金新版徽章 1 枚。

开奖规则

  将于9月11日(星期六下午|晚上开奖),随机方式抽取。

结语

  本次基于Spring Boot集成AutoGenerator代码生成器的项目就完成了,粗枝大叶的建立了一个快速代码生成的框架,当然还有更深入的配置参数去满足个性化的需求。本文主要针对新手入门练习使用,也作为基础查询手册使用,希望本文可以帮助到你。感谢阅读。

  作者介绍:【小阿杰】一个爱鼓捣的程序猿,JAVA开发者和爱好者。公众号【Java全栈架构师】维护者,欢迎关注阅读交流。

  好了,感谢您的阅读,希望您喜欢,如对您有帮助,欢迎点赞收藏。如有不足之处,欢迎评论指正。下次见。