告别繁琐!MapStruct-Plus 让对象映射效率飙升,这波操作太香了!

news/2025/12/11 4:02:56/文章来源:https://www.cnblogs.com/linyb-geek/p/19010673

你是否还在为对象映射转换写一堆重复的 getter/setter?是否因 Apache BeanUtils 的性能问题头疼?又或是觉得 MapStruct 的手动定义 Mapper 接口不够“智能”?

今天要给大家安利一款“效率神器”——MapStruct-Plus。作为 MapStruct 的增强版,它不仅完美继承了 MapStruct 的编译期转换、高性能优势,还通过“自动生成 Mapper 接口”等黑科技,让 Java 类型转换变得简单到离谱!

MapStruct-Plus:不止于“增强”,更是“解放双手”

1. 它到底是什么?

MapStruct-Plus 是基于 MapStruct 开发的增强工具,核心目标是让对象映射更简单、更优雅

  • 底层不变:和 MapStruct 一样,基于 JSR 269 注解处理器,编译期生成转换代码,性能远超反射型工具(如 BeanUtils)。
  • 无缝兼容:内嵌 MapStruct 核心,已用 MapStruct 的项目可直接替换依赖,无需重构代码。
  • 核心升级:最爽的是自动生成 Mapper 接口,不用再手动定义转换接口,开发者只需关注“转换规则”即可。

2. 为什么选它?5 大核心优势

优势 具体价值
自动生成 Mapper 无需手动编写转换接口,加个注解就搞定,少写 N 行模板代码
增强转换能力 支持嵌套对象、集合、Map 转对象等复杂场景,还能自定义转换逻辑
性能拉满 编译期生成原生 Java 代码,转换速度和手写 getter/setter 几乎无差别
友好的错误提示 编译期报错,直接定位到转换问题,告别运行时“莫名其妙”的 Bug
完美兼容 Lombok 和 @Data、@Builder 等注解无缝配合,避免因“类结构”引发的转换异常

快速上手:3 步实现对象转换

以 Spring Boot 项目为例,带你 5 分钟跑通第一个案例。

步骤 1:引入依赖

pom.xml 中添加 starter 和编译插件(以 1.4.0 版本为例):

<!-- 核心依赖 -->
<dependency><groupId>io.github.linpeilie</groupId><artifactId>mapstruct-plus-spring-boot-starter</artifactId><version>1.4.0</version>
</dependency><!-- 编译插件(需配合 Lombok 调整,见下文说明) -->
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><annotationProcessorPaths><!-- Lombok 依赖(若使用) --><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></path><!-- MapStruct-Plus 处理器 --><path><groupId>io.github.linpeilie</groupId><artifactId>mapstruct-plus-processor</artifactId><version>1.4.0</version></path><!-- Lombok 与 MapStruct 绑定器(Lombok 1.18.16+ 需加) --><path><groupId>org.projectlombok</groupId><artifactId>lombok-mapstruct-binding</artifactId><version>0.2.0</version></path></annotationProcessorPaths></configuration></plugin></plugins>
</build>

步骤 2:定义对象并加注解

只需在源对象上添加 @AutoMapper(target = 目标类.class),无需手动写 Mapper 接口!

// 源对象:UserInfo
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@AutoMapper(target = UserInfoDTO.class) // 指定转换目标
public class UserInfo {private String username;private String password;private String mobile;
}// 目标对象:UserInfoDTO
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserInfoDTO {private String username;private String password;private String mobile;
}

步骤 3:一行代码实现转换

通过 Converter 工具类的 convert 方法直接转换,无需注入 Mapper!

public static void main(String[] args) {Converter converter = new Converter();Faker faker = new Faker(Locale.CHINA);// 模拟一个 UserInfo 对象UserInfo user = UserInfo.builder().username(faker.name().fullName()).password(faker.internet().password()).mobile(faker.phoneNumber().cellPhone()).build();// 转换为 UserInfoDTOUserInfoDTO dto = converter.convert(user, UserInfoDTO.class);System.out.println(user); // 输出:UserInfo(username=万智辉, password=jhd05qtk3w, mobile=18887502718)System.out.println(dto); // 输出:UserInfoDTO(username=万智辉, password=jhd05qtk3w, mobile=18887502718)
}

是不是比手写 get/set 快 10 倍? 这还只是基础操作,更强大的功能还在后面!

实战技巧:这些场景用 MapStruct-Plus 太香了

1. 字段名不一致?@AutoMapping 一键映射

当源对象和目标对象字段名不同(如 username vs loginName),无需手动赋值:

// 源对象:UserInfo
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@AutoMapper(target = UserInfoDTO.class)
public class UserInfo {@AutoMapping(target = "loginName") // 映射到目标类的 loginName 字段private String username;private String password;private String mobile;
}// 目标对象:UserInfoDTO
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserInfoDTO {private String loginName; // 对应源对象的 usernameprivate String password;private String mobile;
}// 转换代码:
public static void main(String[] args) {Converter converter = new Converter();Faker faker = new Faker(Locale.CHINA);UserInfo userInfo = UserInfo.builder().username(faker.name().fullName()).password(faker.internet().password()).mobile(faker.phoneNumber().cellPhone()).build();UserInfoDTO dto = converter.convert(userInfo, UserInfoDTO.class);System.out.println(userInfo); // 输出:UserInfo(username=任思聪, password=ry85f0wwwqyf4n, mobile=13165059205)System.out.println(dto); // 输出:UserInfoDTO(loginName=任思聪, password=ry85f0wwwqyf4n, mobile=13165059205)
}

2. 集合转换?直接传 List + 目标类

批量转换 List 时,无需循环调用单对象转换:

public static void main(String[] args) {Converter converter = new Converter();Faker faker = new Faker(Locale.CHINA);// 模拟一个 UserInfo 列表List<UserInfo> userList = new ArrayList<>();UserInfo user = UserInfo.builder().username(faker.name().fullName()).password(faker.internet().password()).mobile(faker.phoneNumber().cellPhone()).build();userList.add(user);// 直接转换为 List<UserInfoDTO>List<UserInfoDTO> dtoList = converter.convert(userList, UserInfoDTO.class);System.out.println(userList); // 输出:[UserInfo(username=马博涛, password=uyxarzq0qji42, mobile=17526506905)]System.out.println(dtoList); // 输出:[UserInfoDTO(loginName=马博涛, password=uyxarzq0qji42, mobile=17526506905)]
}

3. Map 转对象?加个注解就行

从 Map 转换为实体类时,只需在目标类上加 @AutoMapMapper

// 目标对象:UserInfo(加 @AutoMapMapper 支持 Map 转换)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@AutoMapMapper
public class UserInfo {private String username;private String password;private String mobile;
}// 转换代码:
public static void main(String[] args) {Converter converter = new Converter();Faker faker = new Faker(Locale.CHINA);Map<String, Object> map = new HashMap<>();map.put("username", faker.name().fullName());map.put("password", faker.internet().password());map.put("mobile", faker.phoneNumber().cellPhone());System.out.println(map); // 输出:{password=ebcnes0s63fwo0, mobile=15124057127, username=刘嘉熙}UserInfo userInfo = converter.convert(map, UserInfo.class);System.out.println(userInfo); // 输出:UserInfo(username=刘嘉熙, password=ebcnes0s63fwo0, mobile=15124057127)
}

4. 复杂逻辑?自定义转换器搞定

遇到特殊转换(如密码加解密),可自定义转换规则。以“UserInfo 明文密码转 UserInfoDTO 密文密码”为例:

a. 自定义类型转换器

@Component
public class UserConvertRule {// 明文 → 密文(UserInfo → UserInfoDTO 时用)@Named("convertPlainTex2Ciphertext")public String convertPlainTex2Ciphertext(String plainText) {return EncryptionUtil.encrypt(plainText); // 假设 EncryptionUtil 是加密工具类}// 密文 → 明文(UserInfoDTO → UserInfo 时用)@Named("convertCiphertext2PlainText")public String convertCiphertext2PlainText(String ciphertext) {return EncryptionUtil.decrypt(ciphertext); // 解密}
}

b. 在字段上指定转换规则

// 源对象:UserInfo(明文密码)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@AutoMapper(target = UserInfoDTO.class, uses = UserConvertRule.class)
public class UserInfo {@AutoMapping(target = "loginName")private String username;@AutoMapping(qualifiedByName = "convertPlainTex2Ciphertext") // 加密private String password;private String mobile;
}// 目标对象:UserInfoDTO(密文密码)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@AutoMapper(target = UserInfo.class, uses = UserConvertRule.class)
public class UserInfoDTO {private String loginName;@AutoMapping(qualifiedByName = "convertCiphertext2PlainText") // 解密private String password;private String mobile;
}

c. 测试转换效果(Spring 环境下)

@SpringBootTest(classes = MapStructPlusApplication.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class MapStructPlusTest {@Autowiredprivate Converter converter;@Testpublic void testCustomConverter() {Faker faker = new Faker(Locale.CHINA);// UserInfo → UserInfoDTO(明文变密文)UserInfo user = UserInfo.builder().username(faker.name().fullName()).password("123456") // 明文.mobile(faker.phoneNumber().cellPhone()).build();UserInfoDTO dto = converter.convert(user, UserInfoDTO.class);System.out.println(user); // 输出:UserInfo(username=韦志强, password=123456, mobile=17292765672)System.out.println(dto); // 输出:UserInfoDTO(loginName=韦志强, password=ENC@xxx, mobile=17292765672)(ENC@xxx 是加密后的值)// UserInfoDTO → UserInfo(密文变明文)UserInfoDTO dto2 = UserInfoDTO.builder().loginName(faker.name().fullName()).password(EncryptionUtil.encrypt("000000")) // 密文.mobile(faker.phoneNumber().cellPhone()).build();UserInfo user2 = converter.convert(dto2, UserInfo.class);System.out.println(dto2); // 输出:UserInfoDTO(loginName=姜伟祺, password=ENC@yyy, mobile=14577358478)System.out.println(user2); // 输出:UserInfo(username=姜伟祺, password=000000, mobile=14577358478)(解密后得到明文)}
}

总结:为什么推荐 MapStruct-Plus?

  • 效率碾压:自动生成转换代码,告别重复劳动,开发速度提升 50%+。
  • 性能无忧:编译期生成代码,比反射工具(如 BeanUtils)快 10 倍以上。
  • 灵活强大:支持字段映射、集合转换、自定义逻辑,覆盖 99% 的业务场景。
  • 无缝迁移:从 MapStruct 升级零成本,老项目也能轻松接入。

如果你还在为对象转换烦恼,MapStruct-Plus 绝对值得一试

👉 官方文档:https://mapstruct.plus
👉 示例代码:https://github.com/lyb-geek/springboot-learning/tree/master/springboot-mapstruct-plus

赶紧用起来,让对象映射从此成为“举手之劳”!如果觉得有用,别忘了转发给身边的同事哦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/994175.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年316不锈钢水管品牌排名:AQUApipe不锈钢水

本榜单基于市场占有率、产品性能、用户口碑及行业认证多维度筛选,聚焦316不锈钢水管领域的标杆企业,为工程采购、家装选材提供客观参考,助力精准匹配高可靠性流体输送解决方案。 TOP1 推荐:浙江康帕斯流体技术股份…

禅道的产品研发

如图步骤进行产品销售根据其步骤得到以下界面

2025年深圳有实力的微信朋友圈广告品牌企业排行榜,看哪家服

为帮企业高效锁定适配自身需求的微信朋友圈广告合作伙伴,避免选型走弯路,我们从技术落地能力(如定向精准度、创意优化效率)、全链路服务质量(覆盖开户投放、数据复盘)、真实客户口碑(侧重转化效果反馈)及资源整…

2025年北京企业BIP系统选型避坑排行榜,好业财/好会计/制造云/供应链云/人力云/协同云/好生意/税务云/财务云BIP管理系统找哪家

随着数智化浪潮的深入,商业创新平台(BIP)已成为企业转型升级的核心引擎。对于北京这座汇聚了众多大型集团、科创企业及成长型公司的商业中心而言,选择一款契合自身发展需求的BIP系统至关重要。面对市场上琳琅满目的…

2025年AI软件搜索广告结果优质服务商排名,资深投放与精准

在AI技术深度渗透营销领域的2025年,AI软件搜索广告结果的质量直接决定企业流量转化效率。面对市场上鱼龙混杂的服务商,如何选择能提供优质广告结果、资深投放能力的合作伙伴?以下依据技术实力、投放效果、客户口碑,…

对象存储s5cmd常用命令

对象存储s5cmd常用命令# 安装s5cmd apt install -y gdebi-core apt install -y wget wget https://github.com/peak/s5cmd/releases/download/v2.2.1/s5cmd_2.2.1_linux_amd64.deb echo y | gdebi s5cmd_2.2.1_linux_a…

【节点】UnityShaderGraph节点分类介绍

节点分类体系概述 ShaderGraph作为Unity的可视化着色器开发工具,其节点系统按照功能划分为九大核心类别。每类节点承担特定的计算任务,共同构建完整的着色器逻辑链路。以下是基于URP渲染管线的【Unity Shader Graph …

python异步并发任务进度条

python异步并发任务进度条import asyncio import aiohttp from tqdm import tqdm from typing import List, Coroutine, Anyclass AsyncProgressBar:"""异步任务进度条管理器"""def __i…

集成灶烟机吸力大揭秘:排风量与风压表现优异的十大品牌权威榜单

集成灶烟机吸力大揭秘:排风量与风压表现优异的十大品牌权威榜单 在现代厨房生活中,集成灶以其高效的吸油烟能力、节省空间的设计和智能化的操作体验,赢得了越来越多消费者的青睐。然而,面对市场上琳琅满目的品牌和…

2025年长三角泡沫混凝土企业TOP5推荐:高强度发泡混凝土

本榜单依托长三角建筑建材市场调研数据、工程案例落地效果及行业口碑反馈,围绕基础发泡混凝土、保温发泡混凝土、高强度发泡混凝土三大核心产品维度,筛选出5家技术领先、服务可靠的标杆企业,为基建、地产、市政工程…

基于 GEE 利用 WorldPop 素材集批量导出 100 米分辨率人口影像数据与时序分析

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025年视力保健公司权威推荐榜单:视力保护‌/视力健康管理‌/视力健康科技‌‌源头公司精选

随着数字生活与人口结构的变化,视觉健康已成为全民关注的核心健康议题,视力保健行业正经历从单一产品矫正向多技术融合、系统性健康管理的深刻变革。在这一背景下,企业的技术原创性、研发投入的持续性以及解决方案的…

Airflow - Installation

Airflow - Installation frank@ZZHPC:~$ zvact (zvenv) frank@ZZHPC:~$ python --version Python 3.12.3 (zvenv) frank@ZZHPC:~$ pip install apache-airflow (zvenv) frank@ZZHPC:~$ airflow db migrate DB: sqlite:…

2025年无压痕折弯机模具用户好评排行

在金属加工与钣金制造领域,折弯工艺的精度与效率直接关系到最终产品的质量与交付周期。近年来,随着客户对产品外观完整性要求的提升,“无压痕折弯”逐渐成为高附加值场景中的关键需求。所谓无压痕折弯机模具,是指在…

Linux Shell 命令:nohup、、、bg、fg、jobs 总结 - Binge

nohup (不挂断,但是前台执行)nohup 是 no hung up 的缩写,意思是不挂断 。 使用 Xshell 等Linux 客户端工具,远程执行 Linux 脚本时,有时候会由于网络问题,导致客户端失去连接,终端断开,脚本运行一半就意外结…

2025年度传感器生产制造商TOP5推荐,勒振传感器口碑出众

在工业4.0浪潮下,生产制造领域对设备健康监测的需求呈爆发式增长,高精度、高可靠性的振动传感器成为保障设备稳定运行的核心器件。2024年数据显示,工业传感器市场规模突破600亿元,年增速达38%,但32%的用户投诉集中…

2025年重庆五大结构加固补强公司推荐:靠谱的结构加固工程总

本榜单依托川渝地区加固工程市场调研与真实项目口碑,深度筛选十家具备专业资质与实战能力的标杆企业,为构筑物加固、维修改造项目选型提供客观依据,助力精准匹配适配的服务伙伴。 TOP1 推荐:重庆特辰建筑加固工程…

2025年北京口碑好的融资顾问排行榜,新测评精选融资顾问公司

为帮企业破解融资无门、对接低效、成本失控的难题,避免陷入虚假资源坑高收费陷阱,我们从资源匹配精准度(持牌机构合作数量、行业资源覆盖)、收费透明性(无隐性消费占比)、服务落地效率(融资方案交付周期)、客户…

【中间件:Redis】2、单线程Redis高并发原理:I/O多路复用+3大优化点(附多线程对比) - 详解

【中间件:Redis】2、单线程Redis高并发原理:I/O多路复用+3大优化点(附多线程对比) - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !impo…

【2025-12-06】连岳摘抄

23:59不要在乎谁选择什么,也别在乎你的同学、朋友选择什么,在乎适合自己的,只有自己了解自己,选择什么职业努力进取,不成功也没有关系。这个世界大多数人是不成功的,在不成功的道路上也充满了学问,通过不成功对…