一、概述
官网:https://baomidou.com/
官方文档 :https://baomidou.com/pages/56bac0/
官方源码地址: https://gitee.com/baomidou/mybatis-plus
官方原话:
AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成
Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
配置环境
- 开发工具 IDEA
- JDK 15
- 数据库 Mysql 、Oracle …
- 基于SpringBoot开发框架
特性
- 无侵入:Mybatis-Plus 在 Mybatis 的基础上进行扩展,只做增强不做改变,引入 Mybatis-Plus 不会对现有的 Mybatis 构架产生任何影响,而且 MP 支持所有 Mybatis 原生的特性
- 依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring
- 损耗小:启动即会自动注入基本CURD,性能基本无损耗,直接面向对象操作
- 预防Sql注入:内置Sql注入剥离器,有效预防Sql注入攻击
- 通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题
- 支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作
- 支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Entity、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(P.S. 比 Mybatis 官方的 Generator 更加强大!)
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 支持关键词自动转义:支持数据库关键词(order、key……)自动转义,还可自定义关键词
- 内置分页插件:基于Mybatis物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询
- 内置性能分析插件:可输出Sql语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作
二、配置说明
2.1 数据库配置(DataSourceConfig)
基础配置
| 属性 | 说明 | 示例 | 
|---|---|---|
| url | jdbc路径 | jdbc:mysql://localhost:3306/(数据库名称) | 
| username | 数据库账号 | root | 
| password | 数据库密码 | 123456 | 
new DataSourceConfig.Builder("jdbc:mysql://127.0.0.1:3306/mybatis-plus","root","123456")
    .build();
    
可选配置
| 方法 | 说明 | 示例 / 参数 | 
|---|---|---|
| dbQuery(IDbQuery) | 数据库查询 | new MySqlQuery() | 
| schema(String) | 数据库 | schema(部分数据库适用) mybatis-plus | 
| typeConvert(ITypeConvert) | 数据库类型转换器 | new MySqlTypeConvert() | 
| keyWordsHandler(IKeyWordsHandler) | 数据库关键字处理器 | new MySqlKeyWordsHandler() | 
/**
 * 初始化数据源配置
 */
private static DataSourceConfig initDataSourceConfig() {
    return new DataSourceConfig.Builder("jdbc:mysql://127.0.0.1:3306/mybatis-plus","root","123456")
    .dbQuery(new MySqlQuery())
    .schema("mybatis-plus")
    .typeConvert(new MySqlTypeConvert())
    .keyWordsHandler(new MySqlKeyWordsHandler())
    .build();
}
2.2 全局配置(GlobalConfig)
| 方法 | 说明 | 示例 / 参数 | 
|---|---|---|
| fileOverride | 覆盖已生成文件 | 默认值:false | 
| disableOpenDir | 禁止打开输出目录 | 默认值:true | 
| outputDir(String) | 指定输出目录 | projectPath + “/src/main/java”(当前工程路径+"/src/main/java") | 
| author(String) | 作者名 | vinjcent | 
| enableKotlin | 开启 kotlin 模式 | 默认值:false | 
| enableSwagger | 开启 swagger 模式 | 默认值:false | 
| dateType(DateType) | 时间类型 | ONLY_DATE、SQL_PACK、TIME_PACK(jdk1.8以上才支持,推荐使用) | 
| commentDate(String) | 注释日期 | 默认值:yyyy-MM-dd,可使用"“yyyy-MM-dd HH:mm:ss”" | 
/**
 * 初始化全局配置
 */
private static GlobalConfig initGlobalConfig(String projectPath) {
    return new GlobalConfig.Builder()
            .outputDir(projectPath + "/src/main/java")//指定生成文件的根目录
            .author("Jack")             //Author设置作者
            .disableOpenDir()           //禁止打开输出目录,禁止打开输出目录
            //.enableSwagger()            //开启 swagger 模式,开启 swagger 模式
            .fileOverride()             //禁止打开输出目录,默认值:false
            .dateType(DateType.ONLY_DATE)//设置时间类型
            .commentDate("yyyy-MM-dd") //注释日期
            .build();
}
2.3 包配置(PackageConfig)
| 方法 | 说明 | 示例 / 参数 | 
|---|---|---|
| parent(String) | 父包名 | 默认值:com.vinjcent | 
| moduleName(String) | 父包模块名 | 默认值:无 | 
| entity(String) | 实体类 Entity 包名 | 默认值:entity | 
| service(String) | Service 包名 | 默认值:service | 
| serviceImpl(String) | 实现类 Service Impl 包名 | 默认值:service.impl | 
| mapper(String) | Mapper 包名 | 默认值:mapper | 
| mapperXml(String) | Mapper XML 包名 | 默认值:mapper.xml | 
| controller(String) | Controller 包名 | 默认值:controller | 
| other(String) | 自定义文件包名 | 可使用"other",生产一个other文件目录 | 
| pathInfo(Map<OutputFile, String>) | 路径配置信息 | Collections.singletonMap(OutputFile.mapperXml, “D://”) | 
/**
 * 初始化包配置
 */
private static PackageConfig initPackageConfig(String projectPath,String moduleName) {
    Props props = new Props("generator.properties");
    Map<OutputFile, String> pathInfo = new HashMap();
    pathInfo.put(OutputFile.mapperXml, projectPath + "/src/main/resources/mapper/" + moduleName);
    pathInfo.put(OutputFile.other,     projectPath + "/src/main/resources/other/" + moduleName);
    return new PackageConfig
            .Builder()
            .parent(props.getStr("package.base"))  // 父包名
            .moduleName(moduleName)      //父包模块名
            .entity("model")             //实体类 Entity 包名,默认值:entity
            .service("service")          //Service 包名,默认值:entity
            .serviceImpl("service.impl") //实现类 Service Impl 包名	默认值:service.impl
            .mapper("mapper")            //Mapper 包名	默认值:mapper
            .xml("mapper.xml")           //Mapper XML 包名	默认值:mapper.xml
            .controller("controller")    //Controller 包名	默认值:controller
            .other("other")              //自定义文件包名	可使用"other",生产一个other文件目录
            .pathInfo(pathInfo)          //路径配置信息
            .build();
}
2.4 模板配置(TemplateConfig)
| 方法 | 说明 | 示例 / 参数 | 
|---|---|---|
| disable | 禁用所有模板 | |
| disable(TemplateType…) | 禁用模板 | TemplateType.ENTITY | 
| entity(String) | 设置实体模板路径(JAVA) | /templates/entity.java | 
| entityKt(String) | 设置实体模板路径(kotlin) | /templates/entity.java | 
| service(String) | 设置 service 模板路径 | /templates/service.java | 
| serviceImpl(String) | 设置 serviceImpl 模板路径 | /templates/serviceImpl.java | 
| mapper(String) | 设置 mapper 模板路径 | /templates/mapper.java | 
| mapperXml(String) | 设置 mapperXml 模板路径 | /templates/mapper.xml | 
| controller(String) | 设置 controller 模板路径 | /templates/controller.java | 
/**
 * 初始化模板配置
 * 可以对controller、service、entity模板进行配置
 */
private static TemplateConfig initTemplateConfig() {
    return new TemplateConfig.Builder()
            .entity("/templates/vue/entity.java")
            .service("/templates/vue/service.java")
            .serviceImpl("/templates/vue/serviceImpl.java")
            .mapper("/templates/vue/mapper.java")
            .mapperXml("/templates/vue/mapper.xml")
            .controller("/templates/vue/controller.java")
            .build();
}
MyBatis-Plus 原生默认模板:

2.5 注入配置(InjectionConfig)
| 方法 | 说明 | 示例 / 参数 | 
|---|---|---|
| beforeOutputFile(BiConsumer<TableInfo, Map<String, Object>>) | 输出文件之前消费者 | |
| customMap(Map<String, Object>) | 自定义配置 Map 对象 | Collections.singletonMap(“test”, “baomidou”) | 
| customFile(Map<String, String>) | 自定义配置模板文件 | Collections.singletonMap(“test.txt”, “/templates/test.vm”) | 
/**
 * 初始化自定义配置
 */
private static InjectionConfig initInjectionConfig(String projectPath) {
    /**自定义生成模板参数**/
    Map<String,Object> paramMap = new HashMap<>();
    /** 自定义 生成类**/
    Map<String, String> customFileMap = new HashMap();
    customFileMap.put("/api/%sApi.js", "templates/vue/api.js.vm");
    customFileMap.put("/%s/index.vue", "templates/vue/index.vue.vm");
    // 自定义配置
    return new InjectionConfig.Builder()
            .beforeOutputFile((tableInfo, objectMap) -> {
                customFileMap.forEach((key, value) -> {
                    System.out.println(key+ " : " + value);
                });
                System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size());
            })
            .customMap(paramMap)
            .customFile(customFileMap)
            .build();
}
注意 : 使用时注意,自定义模板中使用 %s 转译符不会被替换,要想实现自定义模板的文件名自动替换需要重新模板引擎

这个是原本模板引擎源码部分:

这部分是重写后模板引擎源码部分:

2.6 策略配置(StrategyConfig)
| 方法 | 说明 | 示例 / 参数 | 
|---|---|---|
| enableCapitalMode | 开启大写命名 | 默认值:false | 
| enableSkipView | 开启跳过视图 | 默认值:false | 
| disableSqlFilter | 禁用 sql 过滤 | 默认值:true,语法不能支持使用 sql 过滤表的话,可以考虑关闭此开关 | 
| enableSchema | 启用 schema | 默认值:false,多 schema 场景的时候打开 | 
| likeTable(LikeTable) | 模糊表匹配(sql 过滤) | likeTable 与 notLikeTable 只能配置一项 | 
| notLikeTable(LikeTable) | 模糊表排除(sql 过滤) | likeTable 与 notLikeTable 只能配置一项 | 
| addInclude(String…) | 增加表匹配(内存过滤) | include 与 exclude 只能配置一项 | 
| addExclude(String…) | 增加表排除匹配(内存过滤) | include 与 exclude 只能配置一项 | 
| addTablePrefix(String…) | 增加过滤表前缀 | |
| addTablePrefix(String…) | 增加过滤表前缀 | |
| addTableSuffix(String…) | 增加过滤表后缀 | |
| addFieldPrefix(String…) | 增加过滤字段前缀 | |
| addFieldSuffix(String…) | 增加过滤字段后缀 | |
| entityBuilder | 实体策略配置 | |
| controllerBuilder | controller 策略配置 | |
| mapperBuilder | mapper 策略配置 | |
| serviceBuilder | service 策略配置 | 
new StrategyConfig.Builder()
    .enableCapitalMode()
    .enableSkipView()
    .disableSqlFilter()
    .likeTable(new LikeTable("USER"))
    .addInclude("t_simple")
    .addTablePrefix("t_", "c_")
    .addFieldSuffix("_flag")
    .build();
2.6.1 Entity 策略配置
| 方法 | 说明 | 示例 / 参数 | 
|---|---|---|
| nameConvert(INameConvert) | 名称转换实现 | |
| superClass(Class<?>) | 设置父类 | BaseEntity.class | 
| superClass(String) | 设置父类 | com.baomidou.global.BaseEntity | 
| disableSerialVersionUID | 禁用生成 serialVersionUID | 默认值:true | 
| enableColumnConstant | 开启生成字段常量 | 默认值:false | 
| enableChainModel | 开启链式模型 | 默认值:false | 
| enableLombok | 开启 lombok 模型 | 默认值:false | 
| enableRemoveIsPrefix | 开启 Boolean 类型字段移除 is 前缀 | 默认值:false | 
| enableTableFieldAnnotation | 开启生成实体时生成字段注解 | 默认值:false | 
| enableActiveRecord | 开启 ActiveRecord 模型 | 默认值:false | 
| versionColumnName(String) | 乐观锁字段名(数据库) | |
| versionPropertyName(String) | 乐观锁属性名(实体) | |
| logicDeleteColumnName(String) | 逻辑删除字段名(数据库) | |
| logicDeletePropertyName(String) | 逻辑删除属性名(实体) | |
| naming | 数据库表映射到实体的命名策略 | 默认下划线转驼峰命名:NamingStrategy.underline_to_camel | 
| columnNaming | 数据库表字段映射到实体的命名策略 | 默认为 null,未指定按照 naming 执行 | 
| addSuperEntityColumns(String…) | 添加父类公共字段 | |
| addIgnoreColumns(String…) | 添加忽略字段 | |
| addTableFills(IFill…) | 添加表字段填充 | |
| addTableFills(List) | 添加表字段填充 | |
| idType(IdType) | 全局主键类型 | |
| convertFileName(ConverterFileName) | 转换文件名称 | |
| formatFileName(String) | 格式化文件名称 | 
new StrategyConfig.Builder()
    .entityBuilder()
    .superClass(BaseEntity.class)
    .disableSerialVersionUID()
    .enableChainModel()
    .enableLombok()
    .enableRemoveIsPrefix()
    .enableTableFieldAnnotation()
    .enableActiveRecord()
    .versionColumnName("version")
    .versionPropertyName("version")
    .logicDeleteColumnName("deleted")
    .logicDeletePropertyName("deleteFlag")
    .naming(NamingStrategy.no_change)
    .columnNaming(NamingStrategy.underline_to_camel)
    .addSuperEntityColumns("id", "created_by", "created_time", "updated_by", "updated_time")
    .addIgnoreColumns("age")
    .addTableFills(new Column("create_time", FieldFill.INSERT))
    .addTableFills(new Property("updateTime", FieldFill.INSERT_UPDATE))
    .idType(IdType.AUTO)
    .formatFileName("%sEntity")
    .build();
2.6.2 Controller 策略配置
| 方法 | 说明 | 示例 / 参数 | 
|---|---|---|
| superClass(Class<?>) | 设置父类 | BaseController.class | 
| superClass(String) | 设置父类 | com.baomidou.global.BaseController | 
| enableHyphenStyle | 开启驼峰转连字符 | 默认值:false | 
| enableRestStyle | 开启生成@RestController 控制器 | 默认值:false | 
| convertFileName(ConverterFileName) | 转换文件名称 | |
| formatFileName(String) | 格式化文件名称 | 
new StrategyConfig.Builder()
    .controllerBuilder()
    .superClass(BaseController.class)
    .enableHyphenStyle()
    .enableRestStyle()
    .formatFileName("%sAction")
    .build();
2.6.3 Service 策略配置
| 方法 | 说明 | 示例 / 参数 | 
|---|---|---|
| superServiceClass(Class<?>) | 设置 service 接口父类 | BaseService.class | 
| superServiceClass(String) | 设置 service 接口父类 | com.baomidou.global.BaseService | 
| superServiceImplClass(Class<?>) | 设置 service 实现类父类 | BaseServiceImpl.class | 
| superServiceImplClass(String) | 设置 service 实现类父类 | com.baomidou.global.BaseServiceImpl | 
| convertServiceFileName(ConverterFileName) | 转换 service 接口文件名称 | |
| convertServiceImplFileName(ConverterFileName) | 转换 service 实现类文件名称 | |
| formatServiceFileName(String) | 格式化 service 接口文件名称 | |
| formatServiceImplFileName(String) | 格式化 service 实现类文件名称 | 
new StrategyConfig.Builder()
    .serviceBuilder()
    .superServiceClass(BaseService.class)
    .superServiceImplClass(BaseServiceImpl.class)
    .formatServiceFileName("%sService")
    .formatServiceImplFileName("%sServiceImp")
    .build();
2.6.4 Mapper 策略配置
| 方法 | 说明 | 示例 / 参数 | 
|---|---|---|
| superClass(Class<?>) | 设置父类 | BaseMapper.class | 
| superClass(String) | 设置父类 | com.baomidou.global.BaseMapper | 
| enableMapperAnnotation | 开启 @Mapper 注解 | 默认值:false | 
| enableBaseResultMap | 启用 BaseResultMap 生成 | 默认值:false | 
| enableBaseColumnList | 启用 BaseColumnList | 默认值:false | 
| cache(Class<? extends Cache>) | 设置缓存实现类 | MyMapperCache.class | 
| convertMapperFileName(ConverterFileName) | 转换 mapper 类文件名称 | |
| convertXmlFileName(ConverterFileName) | 转换 xml 文件名称 | |
| formatMapperFileName(String) | 格式化 mapper 文件名称 | |
| formatXmlFileName(String) | 格式化 xml 实现类文件名称 | 
new StrategyConfig.Builder()
    .mapperBuilder()
    .superClass(BaseMapper.class)
    .enableMapperAnnotation()
    .enableBaseResultMap()
    .enableBaseColumnList()
    .cache(MyMapperCache.class)
    .formatMapperFileName("%sDao")
    .formatXmlFileName("%sXml")
    .build();
注意: 使用时,先看清楚归于哪一类的配置,避免出现找不到的情况!
三、MyBatis-Plus Generator
2.1、导入依赖
  <!--使用Controller注解需要使用-->
    <dependencies>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <!--Lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!--自动生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!--pagehelper分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.3.2</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>
            <version>2.3.29</version>
        </dependency>
        <!--springboot测试类-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--Swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
    </dependencies>
2.2、运行类(放在测试类中即可)
package generator;
import cn.hutool.core.util.StrUtil;
import cn.hutool.setting.dialect.Props;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.LikeTable;
import com.baomidou.mybatisplus.generator.config.querys.OracleQuery;
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.function.ConverterFileName;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.baomidou.mybatisplus.generator.fill.Property;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;
import config.TimerVelocityTemplateEngine;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.function.Consumer;
/**
 * MyBatisPlus代码生成器
 * 3.5.1
 */
public class MyBatisPlusGenerator {
    public static void main(String[] args) {
        // 获取当前目录路径
        String projectPath = System.getProperty("user.dir");
        String moduleName = "cctv";//scanner("模块名");
        String[] tableNames = {"MVNO_TARIFF_TABLE"};//scanner("表名,多个英文逗号分割").split(",");
        // 代码生成器: 数据源配置
        AutoGenerator autoGenerator = new AutoGenerator(initDataSourceConfig());
        // 全局配置
        autoGenerator.global(initGlobalConfig(projectPath));
        // 包配置,如模块名、实体、mapper、service、controller等
        autoGenerator.packageInfo(initPackageConfig(projectPath,moduleName));
        // 模板配置
        autoGenerator.template(initTemplateConfig());
        // 自定义配置
        autoGenerator.injection(initInjectionConfig(projectPath));
        // 策略配置
        autoGenerator.strategy(initStrategyConfig(tableNames));
        // 使用Freemarker引擎模板,默认的是Velocity引擎模板
        //autoGenerator.execute(new VelocityTemplateEngine());
        autoGenerator.execute(new TimerVelocityTemplateEngine());
    }
    /**
     * 读取控制台内容信息
     */
    private static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        System.out.println(("请输入" + tip + ":"));
        if (scanner.hasNext()) {
            String next = scanner.next();
            if (StrUtil.isNotEmpty(next)) {
                return next;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }
    /**
     * 初始化数据源配置
     */
    private static DataSourceConfig initDataSourceConfig() {
        // 读取当前源文件配置
        Props props = new Props("generator.properties");
        // jdbc路径
        String url = props.getStr("dataSource.url");
        // 数据库账号
        String username = props.getStr("dataSource.username");
        // 数据库账号
        String password = props.getStr("dataSource.password");
        return new DataSourceConfig
                .Builder(url,username,password) //设置数据源
                .dbQuery(new OracleQuery())     //设置数据库查询器
                .build();
    }
    /**
     * 初始化全局配置
     */
    private static GlobalConfig initGlobalConfig(String projectPath) {
        return new GlobalConfig.Builder()
                .outputDir(projectPath + "/src/main/java")//指定生成文件的根目录
                .author("Jack")             //Author设置作者
                .disableOpenDir()           //禁止打开输出目录,禁止打开输出目录
                //.enableSwagger()            //开启 swagger 模式,开启 swagger 模式
                .fileOverride()             //禁止打开输出目录,默认值:false
                .dateType(DateType.ONLY_DATE)//设置时间类型
                .commentDate("yyyy-MM-dd") //注释日期
                .build();
    }
    /**
     * 初始化包配置
     */
    private static PackageConfig initPackageConfig(String projectPath,String moduleName) {
        Props props = new Props("generator.properties");
        Map<OutputFile, String> pathInfo = new HashMap();
        pathInfo.put(OutputFile.mapperXml, projectPath + "/src/main/resources/mapper/" + moduleName);
        pathInfo.put(OutputFile.other,     projectPath + "/src/main/resources/other/" + moduleName);
        return new PackageConfig
                .Builder()
                .parent(props.getStr("package.base"))  // 父包名
                .moduleName(moduleName)      //父包模块名
                .entity("model")             //实体类 Entity 包名,默认值:entity
                .service("service")          //Service 包名,默认值:entity
                .serviceImpl("service.impl") //实现类 Service Impl 包名	默认值:service.impl
                .mapper("mapper")            //Mapper 包名	默认值:mapper
                .xml("mapper.xml")           //Mapper XML 包名	默认值:mapper.xml
                .controller("controller")    //Controller 包名	默认值:controller
                .other("other")              //自定义文件包名	可使用"other",生产一个other文件目录
                .pathInfo(pathInfo)          //路径配置信息
                .build();
    }
    /**
     * 初始化模板配置
     * 可以对controller、service、entity模板进行配置
     */
    private static TemplateConfig initTemplateConfig() {
        return new TemplateConfig.Builder()
                .entity("/templates/vue/entity.java")
                .service("/templates/vue/service.java")
                .serviceImpl("/templates/vue/serviceImpl.java")
                .mapper("/templates/vue/mapper.java")
                .mapperXml("/templates/vue/mapper.xml")
                .controller("/templates/vue/controller.java")
                .build();
    }
    /**
     * 初始化自定义配置
     */
    private static InjectionConfig initInjectionConfig(String projectPath) {
        /**自定义生成模板参数**/
        Map<String,Object> paramMap = new HashMap<>();
        /** 自定义 生成类**/
        Map<String, String> customFileMap = new HashMap();
        customFileMap.put("/api/%sApi.js", "templates/vue/api.js.vm");
        customFileMap.put("/%s/index.vue", "templates/vue/index.vue.vm");
        // 自定义配置
        return new InjectionConfig.Builder()
                .beforeOutputFile((tableInfo, objectMap) -> {
                    customFileMap.forEach((key, value) -> {
                        System.out.println(key+ " : " + value);
                    });
                    System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size());
                })
                .customMap(paramMap)
                .customFile(customFileMap)
                .build();
    }
    private static Consumer<InjectionConfig.Builder> getInjectionConfigBuilder() {
        return consumer -> {
        };
    }
    /**
     * 初始化策略配置
     */
    private static StrategyConfig initStrategyConfig(String[] tableNames) {
        StrategyConfig.Builder builder = new StrategyConfig.Builder();
        builder
                .enableCapitalMode()//开启大写命名,默认值:false
                //.enableSkipView()//开启跳过视图,默认值:false
                //.disableSqlFilter()//禁用sql过滤,默认值:true,语法不能支持使用 sql 过滤表的话,可以考虑关闭此开关
                //.enableSchema()//启用 schema, 默认值:false,多 schema 场景的时候打开
                .entityBuilder()
                .naming(NamingStrategy.underline_to_camel)//数据库表映射到实体的命名策略,默认下划线转驼峰命名:NamingStrategy.underline_to_camel
                .columnNaming(NamingStrategy.underline_to_camel)//数据库表字段映射到实体的命名策略,	默认为 null,未指定按照 naming 执行
                //.superClass()//设置父类: BaseEntity.class || com.baomidou.global.BaseEntity
                //.idType(IdType.ASSIGN_ID) //全局主键类型
                .disableSerialVersionUID() // 禁用生成 serialVersionUID,默认值:true
                //.enableColumnConstant()//开启生成字段常量,默认值:false
                .enableChainModel()//开启链式模型,默认值:false
                .enableLombok()//开启 lombok 模型,默认值:false
                .enableRemoveIsPrefix()//开启 Boolean 类型字段移除 is 前缀,默认值:false
                .enableTableFieldAnnotation()//开启生成实体时生成字段注解,默认值:false
                //.enableActiveRecord()//开启 ActiveRecord 模型,默认值:false
                //.logicDeleteColumnName("deleted")   // 逻辑删除字段名(数据库)
                //.logicDeletePropertyName("deleted") // 逻辑删除属性名(实体)
                //.addTableFills(new Column("create_time", FieldFill.INSERT)) // 自动填充配置  create_time  update_time 两种方式
                //.addTableFills(new Property("updateTime", FieldFill.INSERT_UPDATE))
                //.versionColumnName("version")   // 开启乐观锁
                .formatFileName("%s")//格式化文件名称
                .controllerBuilder()
                //.superClass()//设置父类: BaseController.class || com.baomidou.global.BaseController
                .enableHyphenStyle() //开启驼峰转连字符,默认值:false
                .enableRestStyle()//开启生成@RestController 控制器,默认值:false
                .formatFileName("%sController")//格式化文件名称
                .serviceBuilder()
                //.superServiceClass() //设置 service 接口父类: BaseService.class || com.baomidou.global.BaseService
                //.superServiceImplClass()//设置 service 实现类父类 : BaseServiceImpl.class || com.baomidou.global.BaseServiceImpl
                .formatServiceFileName("%sService")//格式化 service 接口文件名称
                .formatServiceImplFileName("%sServiceImpl")//格式化 service 实现类文件名称
                .mapperBuilder()
                //.superClass()//设置父类: BaseMapper.class || com.baomidou.global.BaseMapper
                .enableMapperAnnotation()//开启 @Mapper 注解,默认值:false
                .enableBaseResultMap()  //启用 BaseResultMap 生成,默认值:false
                .enableBaseColumnList() //启用 BaseColumnList,默认值:false
                //.convertXmlFileName()
                .formatMapperFileName("%sMapper")//格式化 mapper 文件名称
                .formatXmlFileName("%sMapper");//格式化 xml 实现类文件名称
        //当表名中带*号时可以启用通配符模式
        if (tableNames.length == 1 && tableNames[0].contains("*")) {
            String[] likeStr = tableNames[0].split("_");
            String likePrefix = likeStr[0] + "_";
            builder.likeTable(new LikeTable(likePrefix));
        } else {
            builder.addInclude(tableNames);
        }
        return builder.build();
    }
}
2.3、自定义模板引擎
package config;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import java.io.File;
import java.util.Map;
public class TimerVelocityTemplateEngine extends VelocityTemplateEngine {
    @Override
    protected void outputCustomFile(Map<String, String> customFile, TableInfo tableInfo, Map<String, Object> objectMap) {
        //数据库表映射实体名称
        String entityName = tableInfo.getEntityName();
        String otherPath = this.getPathInfo(OutputFile.other);
        //System.out.println(JsonUtils.toJSONString(tableInfo));
        //数据库表映射实体名称 驼峰命名法
        objectMap.put("humpEentityName",toLowerCaseFirstOne(entityName));
        customFile.forEach((key, value) -> {
            String fileName = String.format(otherPath + File.separator +key,entityName);
            this.outputFile(new File(fileName), objectMap, value);
        });
    }
    /**
     * 首字母转为小写
     * @param s
     * @return
     */
    private  String toLowerCaseFirstOne(String s){
        if(Character.isLowerCase(s.charAt(0))) {
            return s;
        }else {
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
        }
    }
}
2.4、运行结果




















