![image-20240316213036489](https://img-blog.csdnimg.cn/img_convert/6ce38a3409fe68e227abbeb554add565.png)
1.pom文件配置
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
温馨提示:
从上面的pom.xml配置可以看出,使用的mybatis版本为:3.5.3。不同的版本其实现自动生成代码的方式不同,特别是3.5.1及其以上的版本和之前的版本有很大区别。
这是官网中的说明:
![image-20240316211558889](https://img-blog.csdnimg.cn/img_convert/19906f531aee801923fd9059a1aa270a.png)
2.工具类具体代码实现
package com.mycompany.common.utils;
import com.au.sa.common.services.CommonAbstractService;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Collections;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
public class MyBatisAutoGeneratorUtil {
public static final String DB_URL = "jdbc:mysql://{ip}:{port}/{dbName}?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=true&autoReconnect=true";
public static final String DB_USER_NAME = "username";
public static final String DB_PASSWORD = "*****";
public static final String AUTHOR = "xiaohuihui";
private static final String[] SUPPER_ENTITY_CONTAINS_FIELD = {"delete_flag", "version_num", "creation_date", "created_by", "last_update_date", "last_updated_by"};
private static final String DEFAULT_OUT_PUT_DIR = "D://MyBatisPlusAutoGeneratorDir";
private static final String RESP_OUT_PUT_DIR = "D://MyBatisPlusAutoGeneratorDir";
private static final String DEFAULT_PARENT_PACK = "com.au.sa.storeRebate";
private static final String BASE_SUPER_ENTITY_CLASS_NAME = "com.au.sa.storeRebate.common.entity.BaseDbEntity";
private static final String[] TABLE_NAMES = new String[]{"table_name"};
public static void main(String[] args) {
FastAutoGenerator.create(DB_URL, DB_USER_NAME, DB_PASSWORD).globalConfig(builder -> {
builder.author(AUTHOR)
.enableSwagger()
.outputDir(DEFAULT_OUT_PUT_DIR);
}).packageConfig(builder -> {
builder.parent("com.au.sa")
.moduleName("storeRebate")
.pathInfo(Collections.singletonMap(OutputFile.xml, DEFAULT_OUT_PUT_DIR));
}).strategyConfig(builder -> {
builder.addInclude(TABLE_NAMES)
.entityBuilder()
.enableTableFieldAnnotation()
.enableLombok()
.enableFileOverride()
.superClass(BASE_SUPER_ENTITY_CLASS_NAME)
.controllerBuilder()
.superClass(CommonAbstractService.class)
.enableHyphenStyle()
.enableRestStyle()
.enableFileOverride()
.formatFileName("%sController")
.serviceBuilder()
.enableFileOverride()
.formatServiceFileName("%sService")
.formatServiceImplFileName("%sServiceImpl")
.mapperBuilder()
.enableFileOverride()
.enableBaseResultMap()
.enableBaseColumnList()
.formatMapperFileName("%sDao");
}).templateEngine(new FreemarkerTemplateEngine())
.execute();
produceViewObject(false, TABLE_NAMES);
}
private static void produceViewObject(boolean isTablePrefix, String... tableNames) {
for (int i = 0; i < tableNames.length; i++) {
String tableName = tableNames[i];
tableName = isTablePrefix ? tableName.substring(tableName.indexOf("_") + 1) : tableName;
String outPutDir = RESP_OUT_PUT_DIR + "/" + (DEFAULT_PARENT_PACK.replace(".", "/")) + "/resp/";
String baseFileName = underline2Camel(tableName, false);
try {
File outFile = new File(outPutDir);
if (!outFile.exists()) {
outFile.mkdirs();
}
File voFile = new File(outFile, baseFileName + "Resp.java");
if (!voFile.exists()) {
voFile.createNewFile();
}
BufferedReader reader = new BufferedReader(
new FileReader(DEFAULT_OUT_PUT_DIR + "/" + (DEFAULT_PARENT_PACK.replace(".", "/")) + "/entity/"
+ baseFileName + ".java"));
FileWriter fw = new FileWriter(voFile);
String line = null;
String description = null;
String regex = "([\u4e00-\u9fa5]+)";
while ((line = reader.readLine()) != null) {
Matcher matcher = Pattern.compile(regex).matcher(line);
if (matcher.find()) {
description = matcher.group(1);
}
int index = line.indexOf(baseFileName);
if (line.contains("package")) {
line = StringUtils.substringBeforeLast(line, ".") + ".resp;";
} else if (index > -1 && !line.contains("@ApiModel")) {
if (line.contains("+")) {
line = StringUtils.substring(line, 0, index + baseFileName.length()) + "{\" +";
} else {
line = StringUtils.substring(line, 0, index + baseFileName.length()) + "{";
}
line = line.replace(baseFileName, baseFileName + "Resp");
} else if (line.contains("@TableName")) {
description = "";
continue;
} else if (line.contains("@TableField") || line.contains("@TableId")) {
boolean required = true;
for (String col : SUPPER_ENTITY_CONTAINS_FIELD) {
if (line.contains(col) && !StringUtils.equals("version_num", col)) {
required = false;
break;
}
}
description = "";
continue;
} else if (line.contains("@Accessors") || line.contains("@Override") || line.contains("@TableLogic") || line.contains("@Version")) {
continue;
}
line += "\r\n";
fw.write(line);
}
fw.close();
reader.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
public static String underline2Camel(String line, boolean... smallCamel) {
if (StringUtils.isBlank(line)) {
return "";
}
StringBuffer sb = new StringBuffer();
Pattern pattern = Pattern.compile("([A-Za-z\\d]+)(_)?");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
String word = matcher.group();
if ((smallCamel.length == 0 || smallCamel[0]) && matcher.start() == 0) {
sb.append(Character.toLowerCase(word.charAt(0)));
} else {
sb.append(Character.toUpperCase(word.charAt(0)));
}
int index = word.lastIndexOf('_');
if (index > 0) {
sb.append(word.substring(1, index).toLowerCase());
} else {
sb.append(word.substring(1).toLowerCase());
}
}
return sb.toString();
}
}
3.相关配置说明
参考官网:MyBatis-Plus代码生成器配置
#数据库配置(DataSourceConfig)
#基础配置
属性 |
说明 |
示例 |
url |
jdbc 路径 |
jdbc:mysql://127.0.0.1:3306/mybatis-plus |
username |
数据库账号 |
root |
password |
数据库密码 |
123456 |
new DataSourceConfig.Builder("jdbc:mysql://127.0.0.1:3306/mybatis-plus","root","123456")
.build();
#可选配置
方法 |
说明 |
示例 |
dbQuery(IDbQuery) |
数据库查询 |
new MySqlQuery(),只在SQLQuery下生效 |
schema(String) |
数据库 schema(部分数据库适用) |
mybatis-plus |
typeConvert(ITypeConvert) |
数据库类型转换器 |
new MySqlTypeConvert(),只在SQLQuery下生效 |
keyWordsHandler(IKeyWordsHandler) |
数据库关键字处理器 |
new MySqlKeyWordsHandler() |
typeConvertHandler(ITypeConvertHandler) |
类型转换器(默认) |
自定义实现ITypeConvertHandler,只在DefaultQuery下生效 |
databaseQueryClass(AbstractDatabaseQuery) |
数据库查询方式 |
默认DefaultQuery.class(通用元数据), SQLQuery.class(SQL查询) |
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())
.databaseQueryClass(SQLQuery.class)
.build();
new DataSourceConfig.Builder("jdbc:mysql://127.0.0.1:3306/mybatis-plus","root","123456")
.schema("mybatis-plus")
.keyWordsHandler(new MySqlKeyWordsHandler())
.build();
#全局配置(GlobalConfig)
方法 |
说明 |
示例 |
disableOpenDir |
禁止打开输出目录 |
默认值:true |
outputDir(String) |
指定输出目录 |
/opt/baomidou/ 默认值: windows:D:// linux or mac : /tmp |
author(String) |
作者名 |
baomidou 默认值:作者 |
enableKotlin |
开启 kotlin 模式 |
默认值:false |
enableSwagger |
开启 swagger 模式 |
默认值:false |
dateType(DateType) |
时间策略 |
DateType.ONLY_DATE 默认值: DateType.TIME_PACK |
commentDate(String) |
注释日期 |
默认值: yyyy-MM-dd |
new GlobalConfig.Builder()
.fileOverride()
.outputDir("/opt/baomidou")
.author("baomidou")
.enableKotlin()
.enableSwagger()
.dateType(DateType.TIME_PACK)
.commentDate("yyyy-MM-dd")
.build();
#包配置(PackageConfig)
方法 |
说明 |
示例 |
parent(String) |
父包名 |
默认值:com.baomidou |
moduleName(String) |
父包模块名 |
默认值:无 |
entity(String) |
Entity 包名 |
默认值:entity |
service(String) |
Service 包名 |
默认值:service |
serviceImpl(String) |
Service Impl 包名 |
默认值:service.impl |
mapper(String) |
Mapper 包名 |
默认值:mapper |
xml(String) |
Mapper XML 包名 |
默认值:mapper.xml |
controller(String) |
Controller 包名 |
默认值:controller |
other(String) |
自定义文件包名 |
输出自定义文件时所用到的包名 |
pathInfo(Map<OutputFile, String>) |
路径配置信息 |
Collections.singletonMap(OutputFile.mapperXml, “D://”) |
new PackageConfig.Builder()
.parent("com.baomidou.mybatisplus.samples.generator")
.moduleName("sys")
.entity("po")
.service("service")
.serviceImpl("service.impl")
.mapper("mapper")
.xml("mapper.xml")
.controller("controller")
.other("other")
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D://"))
.build();
#模板配置(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 |
new TemplateConfig.Builder()
.disable(TemplateType.ENTITY)
.entity("/templates/entity.java")
.service("/templates/service.java")
.serviceImpl("/templates/serviceImpl.java")
.mapper("/templates/mapper.java")
.mapperXml("/templates/mapper.xml")
.controller("/templates/controller.java")
.build();
#注入配置(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”) 方法 formatNameFunction 可以格式化文件,参考测试用例 H2CodeGeneratorTest.testCustomFileByList |
new InjectionConfig.Builder()
.beforeOutputFile((tableInfo, objectMap) -> {
System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size());
})
.customMap(Collections.singletonMap("test", "baomidou"))
.customFile(Collections.singletonMap("test.txt", "/templates/test.vm"))
.build();
#策略配置(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 只能配置一项 ,支持正则匹配、例如 ^t_.* 所有 t_ 开头的表名 |
addExclude(String…) |
增加表排除匹配(内存过滤) |
include 与 exclude 只能配置一项 ,支持正则匹配、例如 .*st$ 所有 st 结尾的表名 |
addTablePrefix(String…) |
增加过滤表前缀 |
|
addTableSuffix(String…) |
增加过滤表后缀 |
|
addFieldPrefix(String…) |
增加过滤字段前缀 |
|
addFieldSuffix(String…) |
增加过滤字段后缀 |
|
outputFile |
内置模板输出文件处理 |
参考测试用例 H2CodeGeneratorTest.testOutputFile |
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();
#Entity 策略配置
方法 |
说明 |
示例 |
nameConvert(INameConvert) |
名称转换实现 |
|
superClass(Class<?>) |
设置父类 |
BaseEntity.class |
superClass(String) |
设置父类 |
com.baomidou.global.BaseEntity |
disableSerialVersionUID |
禁用生成 serialVersionUID |
默认值:true |
enableFileOverride |
覆盖已生成文件 |
默认值:false |
enableColumnConstant |
开启生成字段常量 |
默认值:false |
enableChainModel |
开启链式模型 |
默认值:false |
enableLombok |
开启 lombok 模型 |
默认值:false |
enableRemoveIsPrefix |
开启 Boolean 类型字段移除 is 前缀 |
默认值:false |
enableTableFieldAnnotation |
开启生成实体时生成字段注解 |
默认值:false |
enableActiveRecord |
开启 ActiveRecord 模型 |
默认值:false |
versionColumnName(String) |
乐观锁字段名(数据库字段) |
versionColumnName与versionPropertyName二选一即可 |
versionPropertyName(String) |
乐观锁属性名(实体) |
versionColumnName与versionPropertyName二选一即可 |
logicDeleteColumnName(String) |
逻辑删除字段名(数据库字段) |
logicDeleteColumnName与logicDeletePropertyName二选一即可 |
logicDeletePropertyName(String) |
逻辑删除属性名(实体) |
logicDeleteColumnName与logicDeletePropertyName二选一即可 |
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")
.logicDeleteColumnName("deleted")
.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();
#Controller 策略配置
方法 |
说明 |
示例 |
superClass(Class<?>) |
设置父类 |
BaseController.class |
superClass(String) |
设置父类 |
com.baomidou.global.BaseController |
enableFileOverride |
覆盖已生成文件 |
默认值:false |
enableHyphenStyle |
开启驼峰转连字符 |
默认值:false |
enableRestStyle |
开启生成@RestController 控制器 |
默认值:false |
convertFileName(ConverterFileName) |
转换文件名称 |
|
formatFileName(String) |
格式化文件名称 |
|
new StrategyConfig.Builder()
.controllerBuilder()
.superClass(BaseController.class)
.enableHyphenStyle()
.enableRestStyle()
.formatFileName("%sAction")
.build();
#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 |
enableFileOverride |
覆盖已生成文件 |
默认值:false |
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();
#Mapper 策略配置
方法 |
说明 |
示例 |
superClass(Class<?>) |
设置父类 |
BaseMapper.class |
superClass(String) |
设置父类 |
com.baomidou.global.BaseMapper |
enableFileOverride |
覆盖已生成文件 |
默认值:false |
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();
#自定义模版支持(DTO\VO等)配置
#Freemarker模版支持(DTO\VO等)配置
public final class EnhanceFreemarkerTemplateEngine extends FreemarkerTemplateEngine {
@Override
protected void outputCustomFile(@NotNull Map<String, String> customFile, @NotNull TableInfo tableInfo, @NotNull Map<String, Object> objectMap) {
String entityName = tableInfo.getEntityName();
String otherPath = this.getPathInfo(OutputFile.other);
customFile.forEach((key, value) -> {
String fileName = String.format(otherPath + File.separator + entityName + "%s", key);
this.outputFile(new File(fileName), objectMap, value);
});
}
}
使用方式样例(其他细节参数请查看文档)
entityDTO.java.ftl 可参考源码内entity.java.ftl文件
FastAutoGenerator.create(url, username, password)
.globalConfig(builder -> {
builder.author("abc")
.enableSwagger()
.fileOverride()
.disableOpenDir()
.outputDir(finalProjectPath + "/src/main/java");
})
.packageConfig(builder -> {
builder.parent("com.baomidou.mybatisplus.samples")
.moduleName("test")
.entity("model.entity")
.other("model.dto")
.pathInfo(Collections.singletonMap(OutputFile.xml, finalProjectPath + "/src/main/resources/mapper"));
})
.injectionConfig(consumer -> {
Map<String, String> customFile = new HashMap<>();
customFile.put("DTO.java", "/templates/entityDTO.java.ftl");
consumer.customFile(customFile);
});