业务代码的救星——Java对象转换框架MapStruct

简介:

介绍

在业务项目的开发中,我们经常需要将Java对象进行转换,比如从外部HSF服务得到的对象转换为本域的业务对象domain object,将domain object转为数据持久层的data object,将domain object 转换为DTO以便返回给外部调用方等。在转换时大部分属性都是相同的,只有少部分的不同,如果手工编写转换代码,会很繁琐。这时我们可以通过一些对象转换框架来更方便的做这件事情。

这样的对象转换框架有不少,比较有名的有ModelMapper和MapStruct。它们所使用的实现技术不同,ModelMapper是基于反射的,通过反射来查找实体对象的字段,并读取或写入值,这样的方式实现原理简单,但性能很差。与ModelMapper框架不同的是,MapStruct是基于编译阶段代码生成的,生成的转换代码在运行的时候跟一般的代码一样,没有额外的性能损失。本文重点介绍MapStruct。

原理

image.png

使用方法

1. Mapper声明

通过类似下面的代码声明一个Mapper,MapStruct会在编译时自动生成实现代码。除了基本的功能外,MapStruct提供很多高级的功能,全面支持业务中可能出现各种映射要求。示例代码如下
image.png

简要说明如下
1 - 用Mapper注解标注Mapper接口(也可以是抽象类)
2 - 可以调用其他的Mapper,来转换复杂类型的字段
3 - 可以指定一个Decorator类对Mapper实现做定制
4 - 常用的practice:声明一个静态的INSTANCE,便于调用方引用
5 - 同名的字段会自动映射,不同名的通过Mapping注解指定映射关系和映射方法
6 - 嵌套对象映射,映射到字段的成员,或成员的成员等
7 - 通过源类型和目标类型不能确定mapper的情况下,可以给mapping方法命名,在使用的时候指定特定名字的mapping方法
8 - 用constant来指定映射为一个常量值
9 - 用@MappingTarget注解指定update方法的参数中代表目标对象的参数
10 - 通过@InheritConfiguration重用映射配置,避免重复配置

上面这些特性,1,4,5,9是基本功能,使用时候一般都会用到,其他的是相对高级些的功能,可根据需要选用。MapStruct还支持列表映射,等等更多功能,不一一列举。可以参考文末的参考文档 MapStruct Reference Guide。

另外,MapStruct提供IDE插件,能够在编写映射的时候提供辅助,比如自动代码提示,重构辅助等。

2. 调用Mapper

代码如下
image.png

3. 整合进Maven

添加dependency
image.png

为Maven compile plugin设置annotation processor
image.png

4. 整合进IDE

Enable annotation processor
image.png

安装插件
使用MapStruct,有一个缺点就是,当属性改名的时候,因为在Mapper上注解中配置的名字,是在字符串里面,是不会自动同步的。但是MapStruct提供了插件来做到这一点,同时还提供代码自动提示,跳转到实现等功能。关于插件的更多信息,见 MapStruct support for IntelliJ IDEA
image.png

5. Trouble Shooting

  • 找不到注释处理程序:在pom.xml中增加mapstruct-processor的依赖
  • 没有找到实现类:在pom.xml中加入对mapstruct-processor的依赖
  • 在IDEA里面enable Annotation Processor
  • 使用Lombok的情况下,编译时报Data类的setter/getter找不到:把lombok加入到annotationProcessorPath,如下图
    image.png

参考资料

MapStruct实体间转换快速入门
https://blog.csdn.net/lx_yoyo/article/details/75061614

JDK IO 2017 - Thomas Much - Easy Bean Mappings with MapStruct 1.2
https://www.youtube.com/watch?v=kKK9SczGa3I

MapStruct 1.2.0.Final Reference Guide
http://mapstruct.org/documentation/stable/reference/html

JAVA Annotation Processing技术——Lombok & MapStruct 介绍与使用
https://www.atatech.org/articles/45619

是时候去掉set/get了---浅谈data mapping技术
https://www.atatech.org/articles/45456

Lombok/Mapstruct problem: Cannot find symbol #1270
https://github.com/mapstruct/mapstruct/issues/1270

目录
相关文章
|
5天前
|
存储 安全 Java
Java 集合框架中的老炮与新秀:HashTable 和 HashMap 谁更胜一筹?
嗨,大家好,我是技术伙伴小米。今天通过讲故事的方式,详细介绍 Java 中 HashMap 和 HashTable 的区别。从版本、线程安全、null 值支持、性能及迭代器行为等方面对比,帮助你轻松应对面试中的经典问题。HashMap 更高效灵活,适合单线程或需手动处理线程安全的场景;HashTable 较古老,线程安全但性能不佳。现代项目推荐使用 ConcurrentHashMap。关注我的公众号“软件求生”,获取更多技术干货!
27 3
|
2月前
|
Java 数据库
在Java中使用Seata框架实现分布式事务的详细步骤
通过以上步骤,利用 Seata 框架可以实现较为简单的分布式事务处理。在实际应用中,还需要根据具体业务需求进行更详细的配置和处理。同时,要注意处理各种异常情况,以确保分布式事务的正确执行。
|
2月前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
12天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
35 3
|
2月前
|
Java
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
56 24
|
20天前
|
前端开发 Java 测试技术
java日常开发中如何写出优雅的好维护的代码
代码可读性太差,实际是给团队后续开发中埋坑,优化在平时,没有那个团队会说我专门给你一个月来优化之前的代码,所以在日常开发中就要多注意可读性问题,不要写出几天之后自己都看不懂的代码。
56 2
|
1月前
|
Java 编译器 数据库
Java 中的注解(Annotations):代码中的 “元数据” 魔法
Java注解是代码中的“元数据”标签,不直接参与业务逻辑,但在编译或运行时提供重要信息。本文介绍了注解的基础语法、内置注解的应用场景,以及如何自定义注解和结合AOP技术实现方法执行日志记录,展示了注解在提升代码质量、简化开发流程和增强程序功能方面的强大作用。
81 5
|
1月前
|
存储 算法 Java
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
57 5
|
2月前
|
存储 缓存 安全
Java 集合框架优化:从基础到高级应用
《Java集合框架优化:从基础到高级应用》深入解析Java集合框架的核心原理与优化技巧,涵盖列表、集合、映射等常用数据结构,结合实际案例,指导开发者高效使用和优化Java集合。
44 4
|
2月前
|
Java API 开发者
Java中的Lambda表达式:简洁代码的利器####
本文探讨了Java中Lambda表达式的概念、用途及其在简化代码和提高开发效率方面的显著作用。通过具体实例,展示了Lambda表达式如何在Java 8及更高版本中替代传统的匿名内部类,使代码更加简洁易读。文章还简要介绍了Lambda表达式的语法和常见用法,帮助开发者更好地理解和应用这一强大的工具。 ####