Skip to content

mybatis-plus 3.5代码生成器

参考:代码生成器配置新 | MyBatis-Plus (baomidou.com)

引入依赖

xml
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.4.1</version>
</dependency>

生成工具类

java
package com.lautrans.utils;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;

import java.util.*;

/**
 * @program: pasture
 * @ClassName GenerateCode
 * @author: liupengxiang
 * @create: 2023-11-17 15:55
 * @description: mp逆向工程
 * @Version 1.0
 **/
public class GenerateCode {

    /**
     * 读取控制台内容
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入" + tip + ":");
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

    public static void main(String[] args) {
        String projectPath = System.getProperty("user.dir");
        // 代码生成器
        Map<String, String> customFile = new HashMap<>();
        FastAutoGenerator.create(
                "jdbc:mysql://***.mysql.rds.aliyuncs.com:3306/lautrans?serverTimezone=Asia/Shanghai",
                "username",
                "password"
                ).globalConfig(builder -> {
                    builder.author("lau-trans")
                            .dateType(DateType.ONLY_DATE)
                            .outputDir(projectPath + "/src/main/java")
                            .disableOpenDir()
                            .enableSwagger()
                            .build();
                }).packageConfig(builder -> {
                    builder.parent("com.lautrans")
                            .controller("controller")
                            .service("service")
                            .serviceImpl("service.impl")
                            .entity("entity")
                            .mapper("mapper")
                            .pathInfo(Collections.singletonMap(OutputFile.xml,projectPath + "/src/main/resources/mapper"));
                }).strategyConfig(builder -> {
                    builder.addInclude(scanner("表名,多个英文逗号分割").split(","))
                            //表前缀
                            .addTablePrefix("")
                            //entity配置
                            .entityBuilder()
                            .enableLombok()
                            .naming(NamingStrategy.underline_to_camel)
                            .columnNaming(NamingStrategy.underline_to_camel)
//                            .enableFileOverride()
                            .enableTableFieldAnnotation()
                            .addTableFills(new Column("create_time", FieldFill.INSERT))
                            // 会在实体类的该字段上追加注解[@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)]
                            .addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE))
                            //controller配置
                            .controllerBuilder()
                            .formatFileName("%sController")
                            .enableRestStyle()
                            //service配置
                            .serviceBuilder()
                            .formatServiceFileName("I%sService")
                            .formatServiceImplFileName("%sServiceImpl")
                            //dao配置
                            .mapperBuilder()
                            .superClass(BaseMapper.class)
                            .formatMapperFileName("%sMapper")
                            .formatXmlFileName("%sMapper")
                            .enableMapperAnnotation();
    //                                    .mapperAnnotation();

                })
//                .templateConfig((Scanner, builder) -> {
//                    builder.entity("templates/entity.java")
//                            .mapper("templates/mapper.java")
//                            .service("templates/service.java")
//                            .serviceImpl("templates/serviceImpl.java")
//                            .controller("templates/controller.java")
//                            .xml("templates/mapper.xml");
//                })
                .injectionConfig(builder -> {
                    builder.beforeOutputFile((tableInfo, objectMap) ->
                                    System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size())) //输出文件之前消费者
                            .customFile(customFile) //自定义配置模板文件
                            .build();//加入构建队列
                })
                // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .templateEngine(new VelocityTemplateEngine())
                .execute();
    }

}

生成器流程图

mermaid
flowchart TD
    A["配置数据源"] --> B["读取数据库表"]
    B --> C["配置包名和策略"]
    C --> D["选择模板引擎"]
    D --> E["生成 Entity / Mapper / Service"]
    E --> F["人工检查并二次调整"]

为什么生成后还要人工调整

代码生成器只能根据表结构生成模板代码,不理解业务语义。如果直接使用,可能出现接口直接暴露 Entity、事务缺失、DTO 缺失、权限校验缺失等风险。

Demo 检查项

  1. Entity 字段是否需要脱敏。
  2. Controller 是否应该删除或改成内部接口。
  3. Service 是否需要补事务。
  4. Mapper 是否需要补复杂查询。
  5. 生成路径是否会覆盖手写代码。