mybatis-plus-generator 3.5.1代码生成器实战

简介

在开发的过程中,有很多重复的crud的操作,对于单表的增删改查除了表名不一样,整个逻辑其实都是大同小异的,虽然说增删改查技术上没有什么难度,但是总是要人去写,所以我之前每次写这部分代码的时候就感觉不得劲呀,让人感觉到很是无聊,便搜了搜,有没有什么办法可以一键生成单表的增删改查的,还真有,于是尝试了下,感觉还不错。为了解放我们的双手,减少重复性代码的编写,我推荐使用插件:mybatis-plus-generator 进行代码自动生成单表的简单操作。
下面我将详细介绍通过 mybatis-plus-generator 插件自动生成 controller、service、mapper、serviceImpl相关代码,以及如果你对前端所有兴趣,这个插件还可以做到一键生成对应前端的分页查询、新增、删除、修改等功能。
官方文档:https://baomidou.com/pages/981406/

1.环境搭建

<!-- 生成器 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.1</version>
        </dependency>

        <!--  mapStruct开始  -->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>1.4.2.Final</version>
        </dependency>
        <!--mapstruct编译-->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>1.4.2.Final</version>
        </dependency>
		<!-- web包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
	 <!--velocity模板-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>

        <!-- freemarker模板 -->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
        </dependency>

        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>


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

2.核心配置

1. 数据库的字段

 /**
 * 数据库地址
 */
private static final String DATA_SOURCE = "jdbc:mysql://xxx.xxx.xxx.xxx:3306/你的数据库?userUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8";

/**
 * 用户名
 */
private static final String USERNAME = "用户名";

/**
 * 密码
 */
private static final String PASSWORD = "密码";

2.数据库的配置

  /**
 * 功能描述:
 * 〈 数据库配置 〉
 *
 * @param map 枚举值
 * @return : com.baomidou.mybatisplus.generator.config.DataSourceConfig.Builder
 * @throws
 * @author : yls
 * @date : 2023/4/3 9:58
 */
private static DataSourceConfig.Builder getDataSourceBuilder(Map<String, IColumnType> map) {
    // 数据源配置
    return new DataSourceConfig
            .Builder(
            DATA_SOURCE,
            USERNAME,
            PASSWORD)
            .dbQuery(new MySqlQuery())
            .keyWordsHandler(new MySqlKeyWordsHandler() {
                @Override
                public boolean isKeyWords(String columnName) {
                    //获取当前正在生成的字段名称
                    fieldName = columnName;
                    return this.getKeyWords().contains(columnName.toUpperCase(Locale.ENGLISH));
                }
            })
            .typeConvert(new MySqlTypeConvert() {
                             @Override
                             public IColumnType processTypeConvert(GlobalConfig globalConfig,
                                                                   String fieldType) {
                                 //根据字段名称判断是否需要转换为枚举
                                 if (map.get(fieldName) != null) {
                                     return map.get(fieldName);
                                 }
                                 return super.processTypeConvert(globalConfig, fieldType);
                             }
                         }
            );
}

3.全局的配置

  /**
     * 功能描述:
     * 〈 全局配置 〉
     *
     * @param projectPath 项目路径
     * @return : java.util.function.Consumer<com.baomidou.mybatisplus.generator.config.GlobalConfig.Builder>
     * @throws
     * @author : yls
     * @date : 2023/4/3 9:56
     */
    private static Consumer<GlobalConfig.Builder> getGlobalConfigBuilder(String projectPath) {
        return builder -> {
            //作者
            builder.fileOverride().author("作者名称")
                    //输出路径(写到java目录)
                    .outputDir(projectPath + "\\mybatis-plus-generator\\src\\main\\java")
                    //开启swagger
                    .enableSwagger()
                    .commentDate("yyyy-MM-dd");
        };
    }

4.分包配置

这个主要是设置你的controller、service、mapper、model的类存放父级包名
/**
     * 功能描述:
     * 〈 分包配置 〉
     *
     * @param
     * @return : java.util.function.Consumer<com.baomidou.mybatisplus.generator.config.PackageConfig.Builder>
     * @throws
     * @author : yls
     * @date : 2023/4/3 9:56
     */
    private static Consumer<PackageConfig.Builder> getPackageConfigBuilder(String model) {
        return builder -> builder.parent("com.xxx.xxx")
                .moduleName(model)
                .entity("model")
                .other("model.data")
                .service("service")
                .serviceImpl("service.impl")
                .controller("controller")
                .mapper("mapper")
                .xml("mappers")
                .pathInfo(Collections.singletonMap(OutputFile.mapperXml,
                        System.getProperty("user.dir") + "\\mybatis-plus-generator\\src\\main\\resources\\mappers\\web"));
    }

5. 自定义模板配置

由于每个人的风格不一样,可以根据自己的风格来配置模块
   /**
 * 功能描述:
 * 〈 自定义模板配置 〉
 *
 * @return : java.util.function.Consumer<com.baomidou.mybatisplus.generator.config.InjectionConfig.Builder>
 * @throws
 * @author : yls
 * @date : 2023/4/3 9:57
 */
private static Consumer<InjectionConfig.Builder> getInjectionConfigBuilder() {
    // 模块名称
    return consumer -> {
        Map<String, String> customFile = new HashMap<>(3);
        customFile.put("dto"+ File.separator+"%sDTO.java", "templates/other/dto.java.ftl");
        customFile.put("vo"+ File.separator+"%sVO.java", "templates/other/vo.java.ftl");
        customFile.put("query"+ File.separator+"%sQuery.java", "templates/other/Query.java.ftl");
        customFile.put("converter"+ File.separator+"%sConverter.java", "templates/other/converter.java.ftl");
        // ui页面
        customFile.put("/src/api/%s/index.ts", "templates/ui/api.java.ftl");
        customFile.put("/src/commonSearchFun/%s/index.ts", "templates/ui/search.java.ftl");
        customFile.put("/src/views/%s/constant/index.ts", "templates/ui/constant.java.ftl");
        customFile.put("/src/views/%s/component/add-edit-dialog.vue", "templates/ui/dialog.java.ftl");

        customFile.put("/src/views/%s/handler/add-edit-handler.ts", "templates/ui/addEditHandlerIndex.java.ftl");
        customFile.put("/src/views/%s/handler/index.ts", "templates/ui/handlerIndex.java.ftl");
        customFile.put("/src/views/%s/index.vue", "templates/ui/index.java.ftl");
        consumer.customFile(customFile);
    };
}

6. 策略配置

主要是配置写成的策略
   /**
     * 功能描述:
     * 〈 策略配置 〉
     *
     * @param tables 表集合
     * @return : java.util.function.Consumer<com.baomidou.mybatisplus.generator.config.StrategyConfig.Builder>
     * @throws
     * @author : yls
     * @date : 2023/4/3 9:57
     */
    private static Consumer<StrategyConfig.Builder> getStrategyConfigBuilder(List<String> tables) {
        return builder -> builder.addInclude(tables)
                .addTablePrefix("t_", "t_web")
                // 【service】配置
                .serviceBuilder()
                .formatServiceFileName("I%sService")
                .formatServiceImplFileName("%sServiceImpl")
                // 【实体类】配置
                .entityBuilder()
                .disableSerialVersionUID()
                .superClass("基础的父类")
                .enableLombok()
                //删除的字段配置
                .logicDeleteColumnName("is_deleted")
                .logicDeletePropertyName("deleted")
                .enableTableFieldAnnotation()
                // 【控制器】配置
                .controllerBuilder()
                // 映射路径使用连字符格式,而不是驼峰
                .enableHyphenStyle()
                .formatFileName("%sController")
                .enableRestStyle()
                // 【mapper】的配置
                .mapperBuilder()
                .enableMapperAnnotation()
                //生成通用的resultMap
                .enableBaseResultMap()
                .superClass("你的父类mapper")
                .formatMapperFileName("%sMapper")
                .formatXmlFileName("%sMapper");
    }

7. 核心配置

public static void main(String[] args) {
    // 模块
    String model = "outbound";

    // 表名称
    List<String> tables = new ArrayList<>();
    tables.add("t_web_outbound_details");
    tables.add("t_web_outbound_inventory");

    //枚举字段
    Map<String, IColumnType> map = new HashMap<>(16);
    map.put("role_type", RoleTypeEnum.USER);

    // 生成代码主程序
    autoGeneratorMain(tables, model, map);

}

/**
 1. 功能描述:
 2. 〈 生成器核心配置 〉
 3.  4. @param tables 表集合
 5. @param model 模块名称
 6. @param map 图
 7. @return : void
 8. @author : yls
 9. @date : 2023/4/3 14:44
 10. @throws
 */
private static void autoGeneratorMain(List<String> tables,
                                      String model, Map<String, IColumnType> map) {
    // 工程目录路径
    String projectPath = System.getProperty("user.dir");
    // 数据库配置
    DataSourceConfig.Builder dataSourceConfig = getDataSourceBuilder(map);
    // 生成项目代码
    FastAutoGenerator.create(dataSourceConfig)
            // 全局配置
            .globalConfig(getGlobalConfigBuilder(projectPath))
            // 包配置
            .packageConfig(getPackageConfigBuilder(model))
            // 策略配置
            .strategyConfig(getStrategyConfigBuilder(tables))
            // 自定义DTO\VO\Query
            .injectionConfig(getInjectionConfigBuilder())
            // 使用Freemarker引擎模板,默认的是Velocity引擎模板
            .templateEngine(new CustomFtlTemplateEngine())
            .execute();
}

完整示例

1.测试枚举类

@Getter
public enum RoleTypeEnum implements IColumnType {
    /**
     * 用户角色常量
     */
    WAREHOUSE_MANAGEMENT(0, "测试001"),
    AUDITOR(1, "测试002"),
    USER(2, "普通用户");

    @EnumValue
    @JsonValue
    private int code;

    private String value;

    RoleTypeEnum(int code, String value){
        this.code = code;
        this.value = value;
    }

    /**
     * 返回枚举的名称
     */
    @Override
    public String getType() {
        return "RoleTypeEnum";
    }

    /**
     * 返回包路径包含名称
     * @return
     */
    @Override
    public String getPkg() {
        return "com.ushine.generator.constant.RoleTypeEnum";
    }
}

2.自定义模板解析器,处理生成文件的路径自定义

/**
 * @Author: yls
 * @Date 2023/4/3 14:50
 * @Description: 模板解析器
 * @Version 1.0
 **/
public class CustomFtlTemplateEngine extends FreemarkerTemplateEngine {
    @Override
    protected void outputCustomFile(Map<String, String> customFile, TableInfo tableInfo, Map<String, Object> objectMap) {
        //数据库表映射实体名称
        String entityName = tableInfo.getEntityName();
        String uiSource = NameUtils.toLowerCaseFirstOne(entityName);
        String uiName = NameUtils.camelToUnder(uiSource, "-");
        String otherPath = this.getPathInfo(OutputFile.other);
        customFile.forEach((key, value) -> {
            String fileName;
            String dto = "DTO.java";
            String vo = "VO.java";
            String query = "Query.java";
            String converter = "Converter.java";
            // 前端页面的生成路径
//            String viewPath = System.getProperty("user.dir") + "\\mybatis-plus-generator\\src\\main\\resources\\";
            String viewPath = "D:\\workspace\\xxx";
            if (key.endsWith(dto) ||
                    key.endsWith(vo) ||
                    key.endsWith(query) ||
                    key.endsWith(converter)) {
                fileName = String.format(otherPath + File.separator + key, entityName);
            } else {
                // 前端页面
                fileName = String.format(viewPath + File.separator + key, uiName);
            }
            this.outputFile(new File(fileName), objectMap, value);
        });

    }
}

3.主程序

public class GeneratorMain {
    /**
     * 数据库地址
     */
    private static final String DATA_SOURCE = "jdbc:mysql://ip:3306/数据库?userUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8";

    /**
     * 用户名
     */
    private static final String USERNAME = "用户名";

    /**
     * 密码
     */
    private static final String PASSWORD = "密码";

    /**
     * 字段名称
     */
    private static String fieldName = "";

    public static void main(String[] args) {
        // 模块
        String model = "outbound";

        // 表名称
        List<String> tables = new ArrayList<>();
        tables.add("t_web_test");

        //枚举字段: 自动生成实体类的枚举字段,可以添加多个
        Map<String, IColumnType> map = new HashMap<>(16);
        map.put("role_type", RoleTypeEnum.USER);

        // 生成代码主程序
        autoGeneratorMain(tables, model, map);

    }

    /**
     * 功能描述:
     * 〈 生成器核心配置 〉
     *
     * @param tables 表集合
     * @param model 模块名称
     * @param map 图
     * @return : void
     * @author : yls
     * @date : 2023/4/3 14:44
     * @throws
     */
    private static void autoGeneratorMain(List<String> tables,
                                          String model, Map<String, IColumnType> map) {
        // 工程目录路径
        String projectPath = System.getProperty("user.dir");
        // 数据库配置
        DataSourceConfig.Builder dataSourceConfig = getDataSourceBuilder(map);
        // 生成项目代码
        FastAutoGenerator.create(dataSourceConfig)
                // 全局配置
                .globalConfig(getGlobalConfigBuilder(projectPath))
                // 包配置
                .packageConfig(getPackageConfigBuilder(model))
                // 策略配置
                .strategyConfig(getStrategyConfigBuilder(tables))
                // 自定义DTO\VO\Query
                .injectionConfig(getInjectionConfigBuilder())
                // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .templateEngine(new CustomFtlTemplateEngine())
                .execute();
    }

    /**
     * 功能描述:
     * 〈 数据库配置 〉
     *
     * @param map 枚举值
     * @return : com.baomidou.mybatisplus.generator.config.DataSourceConfig.Builder
     * @throws
     * @author : yls
     * @date : 2023/4/3 9:58
     */
    private static DataSourceConfig.Builder getDataSourceBuilder(Map<String, IColumnType> map) {
        // 数据源配置
        return new DataSourceConfig
                .Builder(
                DATA_SOURCE,
                USERNAME,
                PASSWORD)
                .dbQuery(new MySqlQuery())
                .keyWordsHandler(new MySqlKeyWordsHandler() {
                    @Override
                    public boolean isKeyWords(String columnName) {
                        //获取当前正在生成的字段名称
                        fieldName = columnName;
                        return this.getKeyWords().contains(columnName.toUpperCase(Locale.ENGLISH));
                    }
                })
                .typeConvert(new MySqlTypeConvert() {
                                 @Override
                                 public IColumnType processTypeConvert(GlobalConfig globalConfig,
                                                                       String fieldType) {
                                     //根据字段名称判断是否需要转换为枚举
                                     if (map.get(fieldName) != null) {
                                         return map.get(fieldName);
                                     }
                                     return super.processTypeConvert(globalConfig, fieldType);
                                 }
                             }
                );
    }

    /**
     * 功能描述:
     * 〈 全局配置 〉
     *
     * @param projectPath 项目路径
     * @return : java.util.function.Consumer<com.baomidou.mybatisplus.generator.config.GlobalConfig.Builder>
     * @throws
     * @author : yls
     * @date : 2023/4/3 9:56
     */
    private static Consumer<GlobalConfig.Builder> getGlobalConfigBuilder(String projectPath) {
        return builder -> {
            //作者
            builder.fileOverride().author("yls")
                    //输出路径(写到java目录)
                    .outputDir(projectPath + "\\mybatis-plus-generator\\src\\main\\java")
                    //开启swagger
                    .enableSwagger()
                    .commentDate("yyyy-MM-dd");
        };
    }

    /**
     * 功能描述:
     * 〈 分包配置 〉
     *
     * @param
     * @return : java.util.function.Consumer<com.baomidou.mybatisplus.generator.config.PackageConfig.Builder>
     * @throws
     * @author : yls
     * @date : 2023/4/3 9:56
     */
    private static Consumer<PackageConfig.Builder> getPackageConfigBuilder(String model) {
        return builder -> builder.parent("com.ushine.generator.web")
                .moduleName(model)
                .entity("model")
                .other("model.data")
                .service("service")
                .serviceImpl("service.impl")
                .controller("controller")
                .mapper("mapper")
                .xml("mappers")
                .pathInfo(Collections.singletonMap(OutputFile.mapperXml,
                        System.getProperty("user.dir") + "\\mybatis-plus-generator\\src\\main\\resources\\mappers\\web"));
    }

    /**
     * 功能描述:
     * 〈 自定义模板配置 〉
     *
     * @return : java.util.function.Consumer<com.baomidou.mybatisplus.generator.config.InjectionConfig.Builder>
     * @throws
     * @author : yls
     * @date : 2023/4/3 9:57
     */
    private static Consumer<InjectionConfig.Builder> getInjectionConfigBuilder() {
        // 模块名称
        return consumer -> {
            Map<String, String> customFile = new HashMap<>(3);
            customFile.put("dto"+ File.separator+"%sDTO.java", "templates/other/dto.java.ftl");
            customFile.put("vo"+ File.separator+"%sVO.java", "templates/other/vo.java.ftl");
            customFile.put("query"+ File.separator+"%sQuery.java", "templates/other/Query.java.ftl");
            customFile.put("converter"+ File.separator+"%sConverter.java", "templates/other/converter.java.ftl");
            // ui页面
            customFile.put("/src/api/%s/index.ts", "templates/ui/api.java.ftl");
            customFile.put("/src/commonSearchFun/%s/index.ts", "templates/ui/search.java.ftl");
            customFile.put("/src/views/%s/constant/index.ts", "templates/ui/constant.java.ftl");
            customFile.put("/src/views/%s/component/add-edit-dialog.vue", "templates/ui/dialog.java.ftl");

            customFile.put("/src/views/%s/handler/add-edit-handler.ts", "templates/ui/addEditHandlerIndex.java.ftl");
            customFile.put("/src/views/%s/handler/index.ts", "templates/ui/handlerIndex.java.ftl");
            customFile.put("/src/views/%s/index.vue", "templates/ui/index.java.ftl");
            consumer.customFile(customFile);
        };
    }

    /**
     * 功能描述:
     * 〈 策略配置 〉
     *
     * @param tables 表集合
     * @return : java.util.function.Consumer<com.baomidou.mybatisplus.generator.config.StrategyConfig.Builder>
     * @throws
     * @author : yls
     * @date : 2023/4/3 9:57
     */
    private static Consumer<StrategyConfig.Builder> getStrategyConfigBuilder(List<String> tables) {
        return builder -> builder.addInclude(tables)
                .addTablePrefix("t_", "t_web")
                // 【service】配置
                .serviceBuilder()
                .formatServiceFileName("I%sService")
                .formatServiceImplFileName("%sServiceImpl")
                // 【实体类】配置
                .entityBuilder()
                .disableSerialVersionUID()
                .superClass("自己封装的实体父类")
                .enableLombok()
                .logicDeleteColumnName("is_deleted")
                .logicDeletePropertyName("deleted")
                .enableTableFieldAnnotation()
                // 【控制器】配置
                .controllerBuilder()
                // 映射路径使用连字符格式,而不是驼峰
                .enableHyphenStyle()
                .formatFileName("%sController")
                .enableRestStyle()
                // 【mapper】的配置
                .mapperBuilder()
                .enableMapperAnnotation()
                //生成通用的resultMap
                .enableBaseResultMap()
                .superClass("自己封装的mapper")
                .formatMapperFileName("%sMapper")
                .formatXmlFileName("%sMapper");
    }
}

4.模板

如果需要自定义模板,一般放在resource目录下
在这里插入图片描述

5.测试

点击运行GeneratorMain的main方法,就会在你配置的路径下,生成如下的代码

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值