当前位置: 首页 > ops >正文

SpringBoot3集成MapstructPlus

Mapstruct Plus 是 Mapstruct 的增强工具,在 Mapstruct 的基础上,实现了自动生成 Mapper 接口的功能,并强化了部分功能,使 Java 类型转换更加便捷、优雅。
https://www.mapstruct.plus/

引入依赖

pom.xml

<properties><java.version>21</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><!-- 插件版本 --><maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version><lombok.version>1.18.38</lombok.version><mapstruct-plus.version>1.4.8</mapstruct-plus.version><lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
</properties><dependencyManagement><dependencies><!-- MapStructPlus 依赖https://mvnrepository.com/artifact/io.github.linpeilie/mapstruct-plus-spring-boot-starter--><dependency><groupId>io.github.linpeilie</groupId><artifactId>mapstruct-plus-spring-boot-starter</artifactId><version>${mapstruct-plus.version}</version></dependency></dependencies>
</dependencyManagement><build><plugins><!-- Maven 编译插件 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>${maven-compiler-plugin.version}</version><configuration><source>${java.version}</source>    <!-- 源代码使用的JDK版本 --><target>${java.version}</target>    <!-- 需要生成的目标class文件的编译版本 --><encoding>${project.build.sourceEncoding}</encoding> <!-- 字符集编码,防止中文乱码 --><compilerArgs><arg>-parameters</arg>  <!-- 保留方法参数名称 --></compilerArgs><annotationProcessorPaths><path><groupId>io.github.linpeilie</groupId><artifactId>mapstruct-plus-processor</artifactId> <!-- 定义了一个注解处理器的依赖项, 必须手动配置到此处,才能在编译阶段生成具体的映射实现类,避免运行时的性能开销 --><version>${mapstruct-plus.version}</version></path><!-- 依赖地址:https://mvnrepository.com/artifact/org.projectlombok/lombok-mapstruct-binding解决 Lombok 与 MapStruct 的编译顺序冲突强制 Lombok 在 MapStruct 处理完映射代码后再运行,从而避免字段缺失或无法识别的问题官网提示:https://mapstruct.org/documentation/stable/reference/html/#lombok--><path><groupId>org.projectlombok</groupId><artifactId>lombok-mapstruct-binding</artifactId><version>${lombok-mapstruct-binding.version}</version></path><!--一旦你使用了 <annotationProcessorPaths>,Maven 将只使用你指定的处理器,默认的 Lombok 注解处理器不会自动加入。所以此处需显式添加 Lombok 注解处理器 依赖--><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></path></annotationProcessorPaths></configuration></plugin></plugins>
</build>

封装工具类

公共模块pom.xml

<dependencies><!-- 包含:SpringUtils --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-extra</artifactId></dependency><!-- mapstruct-plus映射工具类 --><dependency><groupId>io.github.linpeilie</groupId><artifactId>mapstruct-plus-spring-boot-starter</artifactId></dependency>
</dependencies>

工具类MapstructUtils.java

package com.zibocoder.plugins.common.util;import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import io.github.linpeilie.Converter;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;import java.util.List;
import java.util.Map;/*** @author zibocoder* @date 2025/7/19 17:34:58* @description Mapstruct工具类*/
@NoArgsConstructor(access = AccessLevel.PRIVATE) // 自动生成一个私有的无参构造方法(禁止实例化:构造函数是私有的,意味着这个类 不能从外部被实例化)
public class MapstructUtils {private final static Converter CONVERTER = SpringUtil.getBean(Converter.class);/*** 将 T 类型对象,转换为 desc 类型的对象并返回** @param source 数据来源实体* @param desc   描述对象 转换后的对象* @return desc*/public static <T, V> V convert(T source, Class<V> desc) {if (ObjectUtil.isNull(source)) {return null;}if (ObjectUtil.isNull(desc)) {return null;}return CONVERTER.convert(source, desc);}/*** 将 T 类型对象,按照配置的映射字段规则,给 desc 类型的对象赋值并返回 desc 对象** @param source 数据来源实体* @param desc   转换后的对象* @return desc*/public static <T, V> V convert(T source, V desc) {if (ObjectUtil.isNull(source)) {return null;}if (ObjectUtil.isNull(desc)) {return null;}return CONVERTER.convert(source, desc);}/*** 将 T 类型的集合,转换为 desc 类型的集合并返回** @param sourceList 数据来源实体列表* @param desc       描述对象 转换后的对象* @return desc*/public static <T, V> List<V> convert(List<T> sourceList, Class<V> desc) {if (ObjectUtil.isNull(sourceList)) {return null;}if (CollUtil.isEmpty(sourceList)) {return CollUtil.newArrayList();}return CONVERTER.convert(sourceList, desc);}/*** 将 Map 转换为 beanClass 类型的集合并返回** @param map       数据来源* @param beanClass bean类* @return bean对象*/public static <T> T convert(Map<String, Object> map, Class<T> beanClass) {if (MapUtil.isEmpty(map)) {return null;}if (ObjectUtil.isNull(beanClass)) {return null;}return CONVERTER.convert(map, beanClass);}
}

实际应用

DeptAddForm->DeptEntity
DeptAddForm.java

package com.zibocoder.system.domain.form;import com.zibocoder.system.domain.entity.DeptEntity;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.hibernate.validator.constraints.Length;/*** @author zibocoder* @date 2025/7/13 06:54:08* @description 部门添加表单*/
@Data
@AutoMapper(target = DeptEntity.class, reverseConvertGenerate = false) //自动映射当前类与 DeptEntity.class 之间的字段对应关系,reverseConvertGenerate = false 表示不生成反向转换方法。
public class DeptAddForm {/*** 部门名称*/@NotBlank(message = "部门名称不能为空")@Length(min = 1, max = 30, message = "部门名称长度不能超过{max}个字符")private String deptName;/*** 父部门ID*/@NotNull(message = "父部门ID不能为空")private Long parentId;/*** 排序*/@NotNull(message = "显示顺序不能为空")private Integer theSort;/*** 备注*/private String remark;
}

DeptEntity.java

package com.zibocoder.system.domain.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;/*** @author zibocoder* @date 2025/7/10 08:16:20* @description 部门实体对象*/
@Data
@TableName(value = "sys_dept", autoResultMap = true)
public class DeptEntity {/*** 部门ID*/@TableId(type = IdType.AUTO)private Long deptId;/*** 部门名称*/private String deptName;/*** 父部门ID*/private Long parentId;/*** 祖级列表*/private String ancestors;/*** 排序*/private String theSort;/*** 部门状态:是否被禁用 false-0否 true-1是*/private Boolean disabledFlag;/*** 备注*/private String remark;
}

业务类 DeptService.java

/*** 新增部门* @param deptAddForm 部门新增表单* @return 响应结果*/
public ResponseResult<Void> addDept(DeptAddForm deptAddForm) {...DeptEntity deptEntity = MapstructUtils.convert(deptAddForm, DeptEntity.class);...deptMapper.insert(deptEntity);return ResponseResult.ok();
}
http://www.xdnf.cn/news/15815.html

相关文章:

  • GaussDB select into和insert into的用法
  • 基于智慧经营系统的学校住宿登记报表分析与应用探究-毕业论文—仙盟创梦IDE
  • Qt--Widget类对象的构造函数分析
  • 上电复位断言的自动化
  • 网络安全初级(前端页面的编写分析)
  • Java 递归方法详解:从基础语法到实战应用,彻底掌握递归编程思想
  • C++STL系列之list
  • Spring Boot 第一天知识汇总
  • UE5多人MOBA+GAS 26、为角色添加每秒回血回蓝(番外:添加到UI上)
  • redis-plus-plus安装与使用
  • 【vue-7】Vue3 响应式数据声明:深入理解 reactive()
  • 敏捷开发的历史演进:从先驱实践到全域敏捷(1950s-2025)
  • ubuntu 24.04 xfce4 钉钉输入抢焦点问题
  • XSS的学习笔记
  • ChatIM项目语音识别安装与使用
  • 拓展面试题之-rabbitmq面试题
  • [Python] -项目实战8- 构建一个简单的 Todo List Web 应用(Flask)
  • pip关于缓存的用法
  • Python Web框架详解:Flask、Streamlit、FastAPI
  • Pinia 核心知识详解:Vue3 新一代状态管理指南
  • 算法-递推
  • 在通信仿真场景下,Python 和 MATLAB 的性能差异主要体现在运行效率、并行计算、库支持、开发效率等方面。以下是基于最新资料的对比总结
  • AS32X601 系列 MCU 硬件最小系统设计与调试方案探析
  • Web-SQL注入数据库类型用户权限架构分层符号干扰利用过程发现思路
  • 基于SHAP的特征重要性排序与分布式影响力可视化分析
  • 两个路由器通过不同的网段互联
  • 【PTA数据结构 | C语言版】邻接矩阵表示的图基本操作
  • TD3与SAC强化学习算法深度对比
  • 六边形滚动机器人cad【7张】三维图+设计书明说
  • Github 贪吃蛇 主页设置