部分笔记,参考官网资料
笔记只讲解基础的使用,更详细的推荐大家阅读官网
⭐️源码:https://gitee.com/zhp1221/java/tree/master/lab_02_mybatis_plus/generate
⭐️相关概念说明:
全局配置:配置数据库相关信息及个人信息
包配置:配置controller,entity,mapper,mapper.xml,service,serviceImpl,Other生成的包路径
Other:自定义模板,详细可看自定义模板讲解,在第二节里
策略配置:表相关信息配置信息
ps: 配置字段,文件名称等等
策略配置细分为:
- Entity 策略配置
- Controller 策略配置
- Service 策略配置
- Mapper 策略配置
ps:配置完这些就可轻松使用代码生成了
代码目录
代码生成
总代码
/**
* 代码生成
*/
public static void generate() {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/community_db?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC",
"root",
"root")
// 全局配置
.globalConfig(builder -> {
builder
.enableSwagger() // 是否启用swagger注解
.author("zhanghp") // 作者名称
.dateType(DateType.ONLY_DATE) // 时间策略
.commentDate("yyyy-MM-dd") // 注释日期
.outputDir("C:\\Dpan\\workspace\\study\\Ibatis_generate\\src\\main\\java") // 输出目录
.fileOverride() // 覆盖已生成文件
.disableOpenDir(); // 生成后禁止打开所生成的系统目录
})
// 包配置
.packageConfig(builder -> {
builder
.parent("com.zhanghp") // 父包名
.moduleName("test") // 模块包名
.entity("dao.entity") // 实体类包名
.service("service") // service包名
.serviceImpl("service.impl") // serviceImpl包名
.mapper("dao.mapper") // mapper包名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, "C:\\Dpan\\workspace\\study\\Ibatis_generate\\src\\main\\resources\\mappers")) // xml位置(还可自定义配置entity,service等位置)
.controller("controller") // controller包名
.other("model"); // 自定义包名
})
// 策略配置
.strategyConfig(builder -> {
builder
.addTablePrefix("t_") // 增加过滤表前缀
.addTableSuffix("_db") // 增加过滤表后缀
.addFieldPrefix("t_") // 增加过滤字段前缀
.addFieldSuffix("_field") // 增加过滤字段后缀
.addInclude("test") // 表匹配
// Entity 策略配置
.entityBuilder()
.enableLombok() // 开启lombok
.enableChainModel() // 链式
.enableRemoveIsPrefix() // 开启boolean类型字段移除is前缀
.enableTableFieldAnnotation() //开启生成实体时生成的字段注解
.versionColumnName("version") // 乐观锁数据库字段
.versionPropertyName("version") // 乐观锁实体类名称
.logicDeleteColumnName("is_deleted") // 逻辑删除数据库中字段名
.logicDeletePropertyName("deleted") // 逻辑删除实体类中的字段名
.naming(NamingStrategy.underline_to_camel) // 表名 下划线 -》 驼峰命名
.columnNaming(NamingStrategy.underline_to_camel) // 字段名 下划线 -》 驼峰命名
.idType(IdType.ASSIGN_ID) // 主键生成策略 雪花算法生成id
.formatFileName("%s") // Entity 文件名称
.addTableFills(new Column("create_time", FieldFill.INSERT)) // 表字段填充
.addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE)) // 表字段填充
.enableColumnConstant()
.enableActiveRecord()
// Controller 策略配置
.controllerBuilder()
.enableRestStyle() // 开启@RestController
.formatFileName("%sController") // Controller 文件名称
// Service 策略配置
.serviceBuilder()
.formatServiceFileName("%sService") // Service 文件名称
.formatServiceImplFileName("%sServiceImpl") // ServiceImpl 文件名称
// Mapper 策略配置
.mapperBuilder()
.enableMapperAnnotation() // 开启@Mapper
.enableBaseColumnList() // 启用 columnList (通用查询结果列)
.enableBaseResultMap() // 启动resultMap
.formatMapperFileName("%sMapper") // Mapper 文件名称
.formatXmlFileName("%sMapper"); // Xml 文件名称
})
.execute(); // 执行
}
生成结果
属性 | 说明 | 示例 |
---|---|---|
url | jdbc 路径 | jdbc:mysql://localhost:3306/community_db |
username | 数据库账号 | root |
password | 数据库密码 | root |
FastAutoGenerator.create("jdbc:mysql://localhost:3306/community_db?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC",
"root",
"root")
方法 | 说明 | 示例 |
---|---|---|
enableSwagger | 开启 swagger注解 | 默认值:false |
author | 作者 | baomidou 默认值:作者 |
dateType(DateType) | 时间策略 | DateType.ONLY_DATE 默认值: DateType.TIME_PACK |
commentDate(String) | 注释日期 | 默认值: yyyy-MM-dd |
outputDir(String) | 指定输出目录 | /opt/baomidou/ 默认值: windows:D:// linux or mac : /tmp |
fileOverride | 覆盖已生成文件 | 默认值:false |
disableOpenDir | 代码生成后,是否打开输出盘符文件夹 | 默认值:true |
代码
// 全局配置
.globalConfig(builder -> {
builder
.enableSwagger() // 是否启用swagger注解
.author("zhanghp") // 作者名称
.dateType(DateType.ONLY_DATE) // 时间策略
.commentDate("yyyy-MM-dd") // 注释日期
.outputDir("C:\\Dpan\\workspace\\study\\Ibatis_generate\\src\\main\\java") // 输出目录
.fileOverride() // 覆盖已生成文件
.disableOpenDir(); // 生成后禁止打开所生成的系统目录
})
方法 | 说明 | 示例 |
---|---|---|
parent(String) | 父包名 | 默认值:com.baomidou |
moduleName(String) | 父包模块名 | 默认值:无 |
entity(String) | Entity 包名 | 默认值:entity |
service(String) | Service 包名 | 默认值:service |
serviceImpl(String) | Service Impl 包名 | 默认值:service.impl |
mapper(String) | Mapper 包名 | 默认值:mapper |
controller(String) | Controller 包名 | 默认值:controller |
other(String) | 自定义文件包名 | 输出自定义文件时所用到的包名 |
pathInfo(Map |
路径输出指定文件夹配置信息 | Collections.singletonMap(OutputFile.mapperXml, “D://”) |
代码演示
// 包配置
.packageConfig(builder -> {
builder
.parent("com.zhanghp") // 父包名
.moduleName("test") // 模块包名
.entity("dao.entity") // 实体类包名
.service("service") // service包名
.serviceImpl("service.impl") // serviceImpl包名
.mapper("dao.mapper") // mapper包名
.controller("controller") // controller包名
.other("model") // 自定义包名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, "C:\\Dpan\\workspace\\study\\Ibatis_generate\\src\\main\\resources\\mappers")); // xml位置
})
方法 | 说明 |
---|---|
addTablePrefix(String…) | 增加过滤表前缀 |
addTableSuffix(String…) | 增加过滤表后缀 |
addFieldPrefix(String…) | 增加过滤字段前缀 |
addFieldSuffix(String…) | 增加过滤字段后缀 |
addInclude(String…) | 增加表匹配(内存过滤) |
代码演示
.strategyConfig(builder -> {
builder
.addTablePrefix("t_") // 增加过滤表前缀
.addTableSuffix("_db") // 增加过滤表后缀
.addFieldPrefix("t_") // 增加过滤字段前缀
.addFieldSuffix("_field") // 增加过滤字段后缀
.addInclude("test") // 表匹配
方法 | 说明 | 示例 |
---|---|---|
enableLombok | 开启 lombok 模型 | 默认值:false |
enableChainModel | 开启链式模型 | 默认值:false |
enableRemoveIsPrefix | 开启 Boolean 类型字段移除 is 前缀 | 默认值:false |
enableTableFieldAnnotation | 开启生成实体时生成字段注解 | 默认值:false |
versionColumnName(String) | 乐观锁字段名(数据库) | |
versionPropertyName(String) | 乐观锁属性名(实体) | |
logicDeleteColumnName(String) | 逻辑删除字段名(数据库) | |
logicDeletePropertyName(String) | 逻辑删除属性名(实体) | |
naming | 数据库表映射到实体的命名策略 | 默认下划线转驼峰命名:NamingStrategy.underline_to_camel |
columnNaming | 数据库表字段映射到实体的命名策略 | 默认为 null,未指定按照 naming 执行 |
convertFileName(ConverterFileName) | 转换文件名称 | |
idType(IdType) | 全局主键类型 | |
formatFileName(String) | 格式化文件名称 | |
addTableFills(IFill…) | 添加表字段填充 | |
addTableFills(List) | 添加表字段填充 | |
enableColumnConstant | 开启生成字段常量 | 默认值:false |
enableActiveRecord | 开启 ActiveRecord 模型 | 默认值:false |
代码演示
// Entity 策略配置
.entityBuilder()
.enableLombok() // 开启lombok
.enableChainModel() // 链式
.enableRemoveIsPrefix() // 开启boolean类型字段移除is前缀
.enableTableFieldAnnotation() //开启生成实体时生成的字段注解
.versionColumnName("version") // 乐观锁数据库字段
.versionPropertyName("version") // 乐观锁实体类名称
.logicDeleteColumnName("is_deleted") // 逻辑删除数据库中字段名
.logicDeletePropertyName("deleted") // 逻辑删除实体类中的字段名
.naming(NamingStrategy.underline_to_camel) // 表名 下划线 -》 驼峰命名
.columnNaming(NamingStrategy.underline_to_camel) // 字段名 下划线 -》 驼峰命名
.idType(IdType.ASSIGN_ID) // 主键生成策略 雪花算法生成id
.formatFileName("%s") // Entity 文件名称
.addTableFills(new Column("create_time", FieldFill.INSERT)) // 表字段填充
.addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE)) // 表字段填充
.enableColumnConstant()
.enableActiveRecord()
方法 | 说明 | 示例 |
---|---|---|
enableRestStyle | 开启生成@RestController 控制器 | 默认值:false |
formatFileName(String) | 格式化文件名称 |
代码演示
// Controller 策略配置
.controllerBuilder()
.enableRestStyle() // 开启@RestController
.formatFileName("%sController") // Controller 文件名称
方法 | 说明 |
---|---|
formatServiceFileName(String) | 格式化 service 接口文件名称 |
formatServiceImplFileName(String) | 格式化 service 实现类文件名称 |
代码演示
// Service 策略配置
.serviceBuilder()
.formatServiceFileName("%sService") // Service 文件名称
.formatServiceImplFileName("%sServiceImpl") // ServiceImpl 文件名称
方法 | 说明 | 示例 |
---|---|---|
enableMapperAnnotation | 开启 @Mapper 注解 | 默认值:false |
enableBaseResultMap | 启用 BaseResultMap 生成 | 默认值:false |
enableBaseColumnList | 启用 BaseColumnList | 默认值:false |
formatMapperFileName(String) | 格式化 mapper 文件名称 | |
formatXmlFileName(String) | 格式化 xml 实现类文件名称 |
代码演示
// Mapper 策略配置
.mapperBuilder()
.enableMapperAnnotation() // 开启@Mapper
.enableBaseColumnList() // 启用 columnList (通用查询结果列)
.enableBaseResultMap() // 启动resultMap
.formatMapperFileName("%sMapper") // Mapper 文件名称
.formatXmlFileName("%sMapper"); // Xml 文件名称
Velocity语法教学
http://www.51gjie.com/javaweb/896.html
# 自定义模板使用的是Velocity模板引擎(也可使用Freemarker)
- 需提前学习Velocity相关语法(语法很简单)
- ps:velocity的注释在一行中一定要顶头(否则生成的java,会在格式中多空格)
方法 | 说明 | 示例 |
---|---|---|
customMap(Map |
自定义配置 Map 对象 | Collections.singletonMap(“test”, “baomidou”) |
customFile(Map |
自定义配置模板文件 | Collections.singletonMap(“test.txt”, “/templates/test.vm”) |
代码演示
customMap我是基于源码增强的,所以没有在InjecttionConfig中配置
ps:自定义模板和map,是根据本人在公司项目中的使用所需进行的封装
// 注入配置
.injectionConfig(builder -> {
// tag::custom file
// 自定义vo,ro,qo等数据模型
Map<String, String> customFile = new HashMap<>();
customFile.put(CustomEnum.VO.getModelSuffix(), CustomEnum.VO.getPath());
customFile.put(CustomEnum.RO.getModelSuffix(), CustomEnum.RO.getPath());
customFile.put(CustomEnum.QO.getModelSuffix(), CustomEnum.QO.getPath());
// 自定义MapStruct
customFile.put(CustomEnum.CONVERTER.getModelSuffix(), CustomEnum.CONVERTER.getPath());
// end::custom file
builder
.customFile(customFile); // 自定义模板
})
.templateEngine(new EnhanceVelocityTemplaEngine())
CustomEnum
注入配置中所引用的类
封装模块后缀,模板路径的枚举类
public enum CustomEnum {
VO("VO", "templates/model/vo.java.vm"),
RO("RO", "templates/model/ro.java.vm"),
QO("QO", "templates/model/qo.java.vm"),
CONVERTER("Converter", "templates/converter/converter.java.vm");
CustomEnum(String modelSuffix, String path) {
this.modelSuffix = modelSuffix;
this.path = path;
}
@Getter
private String modelSuffix;
@Getter
private String path;
public static List<String> getModel(){
List<String> result = new ArrayList<>();
CustomEnum[] values = CustomEnum.values();
for (CustomEnum it : values) {
result.add(it.getModelSuffix());
}
return result;
}
}
内部类 - EnhanceVelocityTemplateEngine
getObjectMap:自定义包路径,返回结果,工具类等
outputCustomFile:输出路径封装
/**
* 代码生成器支持自定义[DTO\VO等]模版
*/
public final static class EnhanceVelocityTemplateEngine extends VelocityTemplateEngine {
@Override
public Map<String, Object> getObjectMap(@NotNull ConfigBuilder config, @NotNull TableInfo tableInfo) {
// 获取实体类名字
String entityName = tableInfo.getEntityName();
// 获取object map
Map<String, Object> objectMap = super.getObjectMap(config, tableInfo);
// 获取Other的盘符路径
String otherPath = (String)((Map<String, Object>) objectMap.get("package")).get("Other");
// 自定义枚举
List<String> modelList = CustomEnum.getModel();
// 循环
modelList.forEach(it -> {
// 转小写
String var = it.toLowerCase();
// 存入object map
objectMap.put(var, otherPath + "." + var + "." + entityName + it);
});
// 自定义converter
objectMap.put("commonConverter", "com.zhanghp.common.converter.CommonConverter");
// converter utils
objectMap.put("converterUtil", "com.zhanghp.common.converter.utils.ConverterUtil");
// 分页
objectMap.put("pageParent", "com.zhanghp.common.model.PageParent");
// utils
objectMap.put("objectUtils", "com.zhanghp.common.utils.ObjectUtils");
// 返回结果封装
objectMap.put("r", "com.zhanghp.common.response.R");
return objectMap;
}
@Override
protected void outputCustomFile(@NotNull Map<String, String> customFile, @NotNull TableInfo tableInfo, @NotNull Map<String, Object> objectMap) {
// 获取实体类名字
String entityName = tableInfo.getEntityName();
// 获取other包盘符路径
String otherPath = this.getPathInfo(OutputFile.other);
// 输出自定义java模板
customFile.forEach((key, value) -> {
// 输出路径
String fileName = otherPath + File.separator + key.toLowerCase() + File.separator + entityName + key +".java";
// 输出velocity的java模板
this.outputFile(new File(fileName), objectMap, value);
});
}
}
controller层引擎模板
更多的代码,可clone我的代码,详细看别的velocity模板用法
package ${package.Controller};
#if(${swagger})
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiOperation;
#end
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import ${package.Service}.${table.serviceName};
import ${ro};
import ${qo};
import ${r};
## 判断是否包含父类
#if(${superControllerClassPackage})
import ${superControllerClassPackage};
#end
/**
*
* $!{table.comment} controller
*
*
* @author ${author}
* @since ${date}
*/
@RequiredArgsConstructor(onConstructor_ = @Autowired)
## swagger相关
#if(${swagger})
@Api(tags = "REST - $!{table.comment}")
#end
## controller注解
#if(${restControllerStyle})
@RestController
#else
@Controller
#end
## 请求地址
@RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
## 类名及继承判断
#if(${superControllerClass})
public class ${table.controllerName} extends ${superControllerClass} {
#else
public class ${table.controllerName} {
#end
## 注入服务类
private final ${table.serviceName} service;
## 主键类型判断
#foreach($field in ${table.fields})
#if(${field.keyFlag})
## 主键类型
#set($idType=${field.propertyType})
## 主键名称
#set($idName=${field.propertyName})
## 跳出
#break
#end
#end
@PostMapping("/create")
#if(${swagger})
@ApiOperation(value = "新增")
#end
public R createOne(@RequestBody ${entity}RO ro){
boolean flag = service.create(ro);
return R.judgeR(flag, flag ? "创建成功" : "创建失败");
}
@DeleteMapping("/delete/{${idName}}")
#if(${swagger})
@ApiOperation(value = "删除")
#end
public R delete(@PathVariable("${idName}")${idType} ${idName}){
boolean flag = service.delete(${idName});
return R.judgeR(flag, flag ? "删除成功" : "删除失败");
}
@PutMapping("/update")
#if(${swagger})
@ApiOperation(value = "修改")
#end
public R update(@RequestBody ${entity}RO ro){
boolean flag = service.update(ro);
return R.judgeR(flag, flag ? "修改成功" : "修改失败");
}
@GetMapping("/{${idName}}")
#if(${swagger})
@ApiOperation(value = "单条查询")
#end
public R getOne(@PathVariable("${idName}")${idType} ${idName}){
return R.success(service.getById(${idName}));
}
@PostMapping("/findList")
#if(${swagger})
@ApiOperation(value = "列表查询")
#end
public R findList(@RequestBody ${entity}QO qo){
return R.success(service.findList(qo));
}
@PostMapping("/findPage")
#if(${swagger})
@ApiOperation(value = "分页查询")
#end
public R findPage(@RequestBody ${entity}QO qo){
return R.success(service.findPage(qo));
}
}
/**
*
* 代码生成:输入生成
*
*
*
* @author zhanghp
* @date 2022-07-16 14:53
*/
public class IbatisScannerGenerate {
public static void main(String[] args) {
generate();
}
/**
* 代码生成
*/
private static void generate() {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/community_db?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC",
"root",
"root")
// 全局配置
.globalConfig((scanner, builder) -> {
builder
.enableSwagger() // 是否启用swagger注解
.author(scanner.apply("请输入作者名称")) // 作者名称
.dateType(DateType.ONLY_DATE) // 时间策略
.commentDate("yyyy-MM-dd") // 注释日期
.outputDir(scanner.apply("请输入-》指定输出目录")) // 输出目录
.fileOverride() // 覆盖已生成文件
.disableOpenDir(); // 生成后禁止打开所生成的系统目录
})
// 包配置
.packageConfig((scanner, builder) -> {
builder
.parent(scanner.apply("清楚如父包路径,如com.***.***")) // 父包名
.moduleName(scanner.apply("请输入模块名称")) // 模块包名
.entity(scanner.apply("请输入实体类包名")) // 实体类包名
.service(scanner.apply("请输入Service层包名")) // service包名
.serviceImpl(scanner.apply("请输入ServiceImpl包名")) // serviceImpl包名
.mapper(scanner.apply("请输入Mapper层包名")) // mapper包名
.controller(scanner.apply("请输入controller层包名")) // controller包名
.other(scanner.apply("请输入自定义包名")); // 自定义包名
})
// 策略配置
.strategyConfig((scanner, builder) -> {
builder
.addTablePrefix(scanner.apply("请输入所要过滤的表前缀")) // 增加过滤表前缀
.addTableSuffix(scanner.apply("请输入所要过滤的表后缀")) // 增加过滤表后缀
.addFieldPrefix(scanner.apply("请输入所要过滤字段前缀")) // 增加过滤字段前缀
.addFieldSuffix(scanner.apply("请输入所要过滤字段后缀")) // 增加过滤字段后缀
.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all"))) // 表匹配
// Entity 策略配置
.entityBuilder()
.enableLombok() // 开启lombok
.enableChainModel() // 链式
.enableRemoveIsPrefix() // 开启boolean类型字段移除is前缀
.enableTableFieldAnnotation() //开启生成实体时生成的字段注解
.versionColumnName(scanner.apply("请输入数据库中的乐观锁字段")) // 乐观锁数据库字段
.versionPropertyName(scanner.apply("请输入字段中的乐观锁名称")) // 乐观锁实体类名称
.logicDeleteColumnName(scanner.apply("请输入数据库中的逻辑删除字段")) // 逻辑删除数据库中字段名
.logicDeletePropertyName(scanner.apply("请输入数据库中的实体名称")) // 逻辑删除实体类中的字段名
.naming(NamingStrategy.underline_to_camel) // 表名 下划线 -》 驼峰命名
.columnNaming(NamingStrategy.underline_to_camel) // 字段名 下划线 -》 驼峰命名
.idType(IdType.ASSIGN_ID) // 主键生成策略 雪花算法生成id
.formatFileName("%s") // Entity 文件名称
.addTableFills(new Column("create_time", FieldFill.INSERT)) // 表字段填充
.addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE)) // 表字段填充
// Controller 策略配置
.controllerBuilder()
.enableRestStyle() // 开启@RestController
.formatFileName("%sController") // Controller 文件名称
// Service 策略配置
.serviceBuilder()
.formatServiceFileName("%sService") // Service 文件名称
.formatServiceImplFileName("%sServiceImpl") // ServiceImpl 文件名称
// Mapper 策略配置
.mapperBuilder()
.enableMapperAnnotation() // 开启@Mapper
.enableBaseColumnList() // 启用 columnList (通用查询结果列)
.enableBaseResultMap() // 启动resultMap
.formatMapperFileName("%sMapper") // Mapper 文件名称
.formatXmlFileName("%sMapper"); // Xml 文件名称
})
// 注入配置
.injectionConfig((scanner, builder) -> {
// 自定义vo,ro,qo等数据模型
Map<String, String> customFile = new HashMap<>();
customFile.put("VO.java", "templates/model/vo.java.vm");
customFile.put("RO.java", "templates/model/ro.java.vm");
customFile.put("QO.java", "templates/model/qo.java.vm");
customFile.put("URO.java", "templates/model/uro.java.vm");
// 自定义MapStruct
customFile.put("Converter.java", "templates/converter/converter.java.vm");
// 自定义配置对象
Map<String, Object> customMap = new HashMap<>();
customMap.put("vo", "VO");
customMap.put("ro", "RO");
customMap.put("qo", "QO");
customMap.put("uro", "URO");
builder
.customFile(customFile) // 自定义模板
.customMap(customMap); // 自定义map
});
}
// 处理 all 情况
protected static List<String> getTables(String tables) {
return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
}
}
⭐️源码:https://gitee.com/zhp1221/java/tree/master/lab_02_mybatis_plus/generate