Mybatis-plus-Generator 3.5.5 自定义模板支持 (DTO/VO 等) 配置
随着项目节奏越来越快,为了减少把时间浪费在新建DTO 、VO 等地方,直接直接基于Mybatis-plus 这颗大树稍微扩展一下,在原来生成PO、 DAO、Service、ServiceImpl、Controller 基础新增。为了解决这个问题,网上找了一堆资料,发现都是老版本的,都是基于老的AutoGenerator ,里面配置非常臃肿,基于FastAutoGenerator 链式实现没有,通过Mybatis-Plus官方文档发现两个核心配置注入配置 (InjectionConfig),下面是官方文档解释

上面是官方文档的案例,存在两个问题,一个并没有other这个属性,第二个框生成的DTO实体会在系统parent目录下。本着要弄就要完美的执着,通过一下午翻阅mybatis-plus-generator 的源码,终于找到定位输出目录类配置CustomFile。下面直接上代码
POM依赖:
<!--gen code start--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.5</version></dependency><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.33</version></dependency><!--gen code ebd-->
构建代码:
FastAutoGenerator.create("jdbc:mysql://xxxx:63306/diboot","diboot", "xxx")//全局配置.globalConfig(builder -> {builder.outputDir(Paths.get(System.getProperty("user.dir")) + "/src/main/java").author("xxx").build();})//包配置.packageConfig(builder -> {builder.parent("com.example.demo").entity("model.po").service("biz").serviceImpl("biz").mapper("dao")// .xml("dao.xml").controller("api.back").build();})//表策略配置.strategyConfig(builder -> {builder.enableSkipView().disableSqlFilter().addTablePrefix("biz_", "sys_").addInclude("biz_article").build();})//entity策略.strategyConfig(builder -> {builder.entityBuilder().idType(IdType.ASSIGN_ID).superClass(BaseModel.class).disableSerialVersionUID().enableRemoveIsPrefix().enableLombok().addIgnoreColumns("is_deleted", "create_time", "update_time").build();})//controller 策略.strategyConfig(builder -> {builder.controllerBuilder().enableHyphenStyle().enableRestStyle().formatFileName("%sController").build();})//Service 策略.strategyConfig(builder -> {builder.serviceBuilder().superServiceClass(IService.class).superServiceImplClass(ServiceImpl.class).formatServiceFileName("%sService").formatServiceImplFileName("%sServiceImpl").build();})//mapper 策略.strategyConfig(builder -> {builder.mapperBuilder().superClass(BaseMapper.class).mapperAnnotation(Repository.class).enableBaseResultMap().enableBaseColumnList().formatMapperFileName("%sMapper").build();})//注入自定义配置.injectionConfig(builder -> {/**自定义生成模板参数,在ftl模版里取值使用**/Map<String,Object> data = new HashMap<>();data.put("entityBuilderModel", true);data.put("chainModel", true);data.put("swagger",true);data.put("entitySerialVersionUID",true);data.put("entityLombokModel", true);builder.customMap(data);List<CustomFile> customFiles = new ArrayList();/**DTO实体**/CustomFile updateInputFile = new CustomFile.Builder().fileName("UpdateInput.java")//生成java文件名称,要和ftl模版里的文件名保持一致.templatePath("/templates/UpdateInput.java.ftl")//实体模板位置.packageName("model.dto")//生成文件包名.build();customFiles.add(updateInputFile);CustomFile addInputFile = new CustomFile.Builder().fileName("AddInput.java").templatePath("/templates/AddInput.java.ftl").packageName("model.dto").build();/**Vo实体**/CustomFile customFileVO = new CustomFile.Builder().fileName("VO.java").templatePath("/templates/VO.java.ftl").packageName("model.vo").build();customFiles.add(customFileVO);customFiles.add(addInputFile);builder.customFile(customFiles);}).templateEngine(new FreemarkerTemplateEngine()).execute();
DTO ftl模版,为了测地解决不需要修改生成实体,根据数据库字段注释生成实体字段注释,根据数据库字段是否允许为空 加上NotBlank 或者 NotNull 以及 @ApiModelProperty 的required 的条件
新增DTO模版代码,已经调试过输出美化内容,有需要的可以直接复制
package ${package.Parent}.model.dto;
<#if swagger>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.Getter;
import lombok.Setter;<#if chainModel>
import lombok.experimental.Accessors;</#if>
</#if>
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.io.Serializable;
import java.io.Serial;
import java.time.*;
/**
* <p>* ${table.comment!}* </p>
*
* @author ${author}
* @since ${date}
*/
<#if entityLombokModel>
@Getter
@Setter<#if chainModel>
@Accessors(chain = true)</#if>
</#if>
<#if swagger>@ApiModel(description = "${table.comment!}")
</#if>
public class ${entity}AddInput implements Serializable {
<#if entitySerialVersionUID>@Serialprivate static final long serialVersionUID = 1L;
</#if>
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field><#if !field.keyFlag && field.propertyName!="tenantId"&&field.propertyName!="museumId"><#--不是主键、不是租户ID 输出--><#if field.comment!?length gt 0><#if field.metaInfo.nullable>@ApiModelProperty(value="${field.comment}")<#else>@ApiModelProperty(value="${field.comment}",required = true)<#if field.propertyType=="string">@NotBlank(message = "${field.comment}不能为空")<#else>@NotNull(message = "${field.comment}不能为空")</#if></#if></#if>private ${field.propertyType} ${field.propertyName};</#if>
</#list>
<#------------ END 字段循环遍历 ---------->
}
生成效果图:自动加上参数校验

修改DTO模版代码
package ${package.Parent}.model.dto;
<#if swagger>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.Getter;
import lombok.Setter;<#if chainModel>
import lombok.experimental.Accessors;</#if>
</#if>
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.io.Serializable;
import java.io.Serial;
import java.time.*;
/**
* <p>* ${table.comment!}* </p>
*
* @author ${author}
* @since ${date}
*/
<#if entityLombokModel>
@Getter
@Setter<#if chainModel>
@Accessors(chain = true)</#if>
</#if>
<#if swagger>@ApiModel(description = "${table.comment!}")
</#if>
public class ${entity}UpdateInput implements Serializable {
<#if entitySerialVersionUID>@Serialprivate static final long serialVersionUID = 1L;
</#if>
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field><#if field.propertyName!="tenantId"&&field.propertyName!="museumId"><#--不是租户ID 输出--><#if field.comment!?length gt 0><#if field.metaInfo.nullable>@ApiModelProperty(value="${field.comment}")<#else>@ApiModelProperty(value="${field.comment}",required = true)<#if field.propertyType=="string">@NotBlank(message = "${field.comment}不能为空")<#else>@NotNull(message = "${field.comment}不能为空")</#if></#if></#if>private ${field.propertyType} ${field.propertyName};</#if>
</#list>
<#------------ END 字段循环遍历 ---------->
}
生成效果图:

VO模版:
package ${package.Parent}.model.vo;
<#if swagger>import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>import lombok.Getter;import lombok.Setter;<#if chainModel>import lombok.experimental.Accessors;</#if>
</#if>
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.io.Serializable;
import java.io.Serial;
import java.time.*;
/**
* <p>* ${table.comment!}* </p>
*
* @author ${author}
* @since ${date}
*/
<#if entityLombokModel>
@Getter
@Setter<#if chainModel>
@Accessors(chain = true)</#if>
</#if>
<#if swagger>@ApiModel(description = "${table.comment!}")
</#if>
public class ${entity}VO implements Serializable {
<#if entitySerialVersionUID>@Serialprivate static final long serialVersionUID = 1L;
</#if>
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field><#if field.propertyName!="tenantId"&&field.propertyName!="museumId"><#--不是租户ID 输出--><#if field.comment!?length gt 0>@ApiModelProperty(value="${field.comment}")</#if>private ${field.propertyType} ${field.propertyName};</#if>
</#list>
<#------------ END 字段循环遍历 ---------->
}
效果图:

项目结构截图:

能看到这里应该有个大概的了解了,既然能生成自定义DTO 和 VO,那我们完全也可以覆盖之前的默认Service,将生成好的 DTO 和VO 放入 Service 模版里,然后将Service模版里 放入Controller模版里,那我们一次性就可以把 PO VO DTO 以及 Service 里增删改查 全部实现,并放到 Controller接口 ,那常用的业务基本上就可以使用了,接口上加上一些权限 注解和日志注解。如果有些特殊的逻辑再生成的service调整即可。后续有时间,把Service的模版也出一个教程。
相关文章:
Mybatis-plus-Generator 3.5.5 自定义模板支持 (DTO/VO 等) 配置
随着项目节奏越来越快,为了减少把时间浪费在新建DTO 、VO 等地方,直接直接基于Mybatis-plus 这颗大树稍微扩展一下,在原来生成PO、 DAO、Service、ServiceImpl、Controller 基础新增。为了解决这个问题,网上找了一堆资料ÿ…...
C#环境下MAC地址获取方法解析
在C#中,获取MAC地址并不是直接支持的,因为出于安全和隐私的考虑,操作系统通常会限制对这类硬件信息的直接访问。不过,仍然可以通过一些方法间接地获取到本地网络接口(比如以太网接口)的MAC地址。 以下是几…...
(k8s)Kubernetes 从0到1容器编排之旅
一、引言 在当今数字化的浪潮中,Kubernetes 如同一艘强大的航船,引领着容器化应用的部署与管理。它以其卓越的灵活性、可扩展性和可靠性,成为众多企业和开发者的首选。然而,要真正发挥 Kubernetes 的强大威力,仅仅掌握…...
Rust Web开发框架对比:Warp与Actix-web
文章目录 Rust Web开发框架对比:Warp与Actix-web引言框架概述Warp框架简介Actix-web框架简介 设计理念Warp的设计理念Actix-web的设计理念 性能比较可扩展性和生态插件和中间件支持社区和文档 使用示例使用Warp构建简单的HTTP服务使用Actix-web构建简单的HTTP服务 学…...
F12抓包12:Performance(性能)前端性能分析
课程大纲 使用场景: ① 前端界面加载性能测试。 ② 导出性能报告给前端开发。 复习:后端(接口)性能分析 ① 所有请求耗时时间轴:“网络”(Network) - 概览。 ② 单个请求耗时:“网络”(Network…...
数据结构(Day13)
一、学习内容 内存空间划分 1、一个进程启动后,计算机会给该进程分配4G的虚拟内存 2、其中0G-3G是用户空间【程序员写代码操作部分】【应用层】 3、3G-4G是内核空间【与底层驱动有关】 4、所有进程共享3G-4G的内核空间,每个进程独立拥有0G-3G的用户空间 …...
链表的快速排序(C/C++实现)
一、前言 大家在做需要排名的项目的时候,需要把各种数据从高到低排序。如果用的快速排序的话,处理数组是十分简单的。因为数组的存储空间的连续的,可以通过下标就可以简单的实现。但如果是链表的话,内存地址是随机分配的…...
css总结(记录一下...)
文字 语法说明word-wrapword-wrap:normal| break-word normal:使用浏览器默认的换行 break-word:允许在单词内换行 text-overflow clip:修剪文本 ellipsis:显示省略符号来代表被修剪的文本 text-shadow可向文本应用的阴影。能够规定水平阴影、垂直阴影、模糊距离,以…...
SpringBoot 处理 @KafkaListener 消息
消息监听容器 1、KafkaMessageListenerContainer 由spring提供用于监听以及拉取消息,并将这些消息按指定格式转换后交给由KafkaListener注解的方法处理,相当于一个消费者; 看看其整体代码结构: 可以发现其入口方法为doStart(),…...
Spring Boot-API版本控制问题
在现代软件开发中,API(应用程序接口)版本控制是一项至关重要的技术。随着应用的不断迭代,API 的改动不可避免,如何在引入新版本的同时保证向后兼容,避免对现有用户的影响,是每个开发者需要考虑的…...
Git 提取和拉取的区别在哪
1. 提取(Fetch) 操作说明:Fetch 操作会从远程仓库下载最新的提交、分支信息等,但不会将这些更改合并到你当前的分支中。它只是将远程仓库的更新信息存储在本地,并不会自动修改你当前的工作区。 使用场景: …...
【数据结构与算法 | 每日一题 | 力扣篇】力扣2390, 2848
1. 力扣2390:从字符串中删除星号 1.1 题目: 给你一个包含若干星号 * 的字符串 s 。 在一步操作中,你可以: 选中 s 中的一个星号。移除星号 左侧 最近的那个 非星号 字符,并移除该星号自身。 返回移除 所有 星号之…...
破解信息架构实施的密码:常见挑战与最佳解决方案全指南
信息架构的成功实施是企业数字化转型的关键步骤,但在实际操作中,企业往往会遇到各种复杂的挑战。这些挑战包括 技术整合的难度、数据管理的复杂性、合规性要求的变化 以及 资源限制 等。《信息架构:商业智能&分析与元数据管理参考模型》为…...
CodeChef Starters 151 (Div.2) A~D
codechef是真敢给分,上把刚注册,这把就div2了,再加上一周没打过还是有点不适应的,好在最后还是能够顺利上分 今天的封面是P3R的设置菜单 我抠出来做我自己的游戏主页了( A - Convert string 题意 在01串里面可以翻转…...
Redis学习——数据不一致怎么办?更新缓存失败了又怎么办?
文章目录 引言正文读写缓存的数据一致性只读缓存的数据一致性删除和修改数据不一致问题操作执行失败导致数据不一致解决办法 多线程访问导致数据不一致问题总结 总结参考信息 引言 最近面试快手的时候被问到了缓存不一致怎么解决?一开始还是很懵的,因为…...
跨境电商代购新纪元:一键解锁全球好物,系统流程全揭秘
添加图片注释,不超过 140 字(可选) 在全球化日益加深的今天,跨境电商代购成为了连接消费者与世界各地优质商品的桥梁。本文将在CSDN平台上,深入剖析跨境电商代购系统的功能流程,带您一窥其背后的技术奥秘与…...
Mac 上终端使用 MySql 记录
文章目录 下载安装终端进入 MySql常用操作查看数据库选择一个数据库查看当前选择的数据库Navcat 打开提示报错参考文章 下载安装 先下载社区版的 MySql 安装的过程需要设置 root 的密码,这个是要进入数据库所设定的,所以要记住 终端进入 MySql 首先输…...
461. 汉明距离
一:题目: 两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。 给你两个整数 x 和 y,计算并返回它们之间的汉明距离。 示例 1: 输入:x 1, y 4 输出:2 解释: 1 (0 0…...
开发指南061-nexus权限管理
平台后台服务的核心是组件,管理组件的软件有: Apache的Archiva、JFrog的Artifactory、Sonatype的Nexus。 本平台选择nexus。nexus的权限模型是用户-角色-权限体系:通过组合权限定义角色,通过给用户赋角色来赋权限。有关nexus的权…...
Qt 弹出菜单右键菜单 QMenu 设置不同颜色的子项
概述 在Qt中,可以使用样式表(StyleSheet)来自定义 QMenu 的外观,包括其子项(如菜单项QAction)的颜色。但是,这通常可以设置 QMenu 的整体样式,而不能单独设置某个子项的颜色。不过&…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
