Java MapStruct 字段映射工具类

2024-05-03 11:04
文章标签 java 工具 映射 mapstruct

本文主要是介绍Java MapStruct 字段映射工具类,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

      • MapStruct 字段映射工具类
        • 1、MapStruct官网
        • 2、MapStruct的使用场景
        • 3、MapStruct的使用
          • A.需要进行转换的实体类
          • B.引入依赖
          • C.定义一个做映射的接口
          • D.测试代码
        • 4、MapStruct处理字段映射
          • A.名字不一致时的映射
          • B.可以自动映射的类型
          • C.自定义常量
          • D. 类型不匹配时的映射
        • 5、MapStruct的性能

MapStruct 字段映射工具类

1、MapStruct官网

MapStruct官网
MapStruct官网示例
Mapstruct是一种代码生成器,它极大地简化了基于"约定优于配置"方法的Java bean类型之间映射
的实现。生成的映射代码使用纯方法调用,因此快速、类型安全且易于理解。

约定优于配置,也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做决定的数
量,获得简单的好处,而又不失灵活性。
2、MapStruct的使用场景

主要用于处理不同业务分层中产生的实体类如在数据存储层,使用DO来抽象一个业务实体;在业务
逻辑层,使用DTO来表示数据传输对象;到了展示层,又把对象封装成VO来与前端进行交互。字段
相差不大而定义了多重类。通过使用get/set方法进行取值赋值。

personDTO.setName(personDO.getName());
personDTO.setAge(personDO.getAge());
personDTO.setSex(personDO.getSex());
personDTO.setBirthday(personDO.getBirthday());
3、MapStruct的使用
A.需要进行转换的实体类
public class PersonDO {private Integer id;private String name;private int age;private Date birthday;private String gender;}public class PersonDTO {private String userName;private Integer age;private Date birthday;private Gender gender;
}
B.引入依赖
...
<properties><org.mapstruct.version>1.4.1.Final</org.mapstruct.version>
</properties>
...<dependencies><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>${org.mapstruct.version}</version></dependency><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${org.mapstruct.version}</version><scope>provided</scope></dependency>
</dependencies>

因为MapStruct需要在编译器生成转换代码,所以需要在maven-compiler-plugin插件中配置上对
mapstruct-processor的引用。

C.定义一个做映射的接口

使用注解@Mapper定义一个Converter接口,在其中定义一个do2dto方法,方法的入参类型是
PersonDO,出参类型是PersonDTO,这个方法就用于将PersonDO转成PersonDTO。

@Mapper
interface PersonConverter {PersonConverter INSTANCE = Mappers.getMapper(PersonConverter.class);@Mappings(@Mapping(source = "name", target = "userName"))PersonDTO do2dto(PersonDO person);
}
D.测试代码
public static void main(String[] args) {PersonDO personDO = new PersonDO();personDO.setName("Fcant");personDO.setAge(18);personDO.setBirthday(new Date());personDO.setId(1);personDO.setGender(Gender.MALE.name());PersonDTO personDTO = PersonConverter.INSTANCE.do2dto(personDO);System.out.println(personDTO);
}

输出结果:

PersonDTO{userName='Fcant', age=18, birthday=Sat Aug 08 19:00:44 CST 2020, gender=MALE}
4、MapStruct处理字段映射

要转换的两个类中源对象属性与目标对象属性的类型和名字一致的时候,会自动映射对应属性。

A.名字不一致时的映射

在PersonDO中用name表示用户名称,而在PersonDTO中使用userName表示用户名。
这时候就要使用@Mapping注解了,只需要在方法签名上,使用该注解,并指明需要转换的源对象
的名字和目标对象的名字就可以了,如将name的值映射给userName,可以使用如下方式:

@Mapping(source = "name", target = "userName")
B.可以自动映射的类型

MapStruct会对部分类型自动做映射,不需要做额外配置。
一般情况下,对于以下情况可以做自动类型转换:

  • 基本类型及其包装类型。

  • 基本类型的包装类型和String类型之间

  • String类型和枚举类型之间

C.自定义常量

在转换映射过程中,给一些属性定义一个固定的值,这个时候可以使用 constant

@Mapping(source = "name", constant = "Fcant")
D. 类型不匹配时的映射
public class PersonDO {private String name;private String address;
}
public class PersonDTO {private String userName;private HomeAddress address;
}
@Mapper
interface PersonConverter {PersonConverter INSTANCE = Mappers.getMapper(PersonConverter.class);@Mapping(source = "userName", target = "name")@Mapping(target = "address",expression = "java(homeAddressToString(dto2do.getAddress()))")PersonDO dto2do(PersonDTO dto2do);default String homeAddressToString(HomeAddress address){return JSON.toJSONString(address);}
}

只需要在PersonConverter中在定义一个方法(因为PersonConverter是一个接口,所以在JDK 1.8以后的版本中可以定义一个default方法),这个方法的作用就是将HomeAddress转换成String类型。

default方法:Java 8 引入的新的语言特性,用关键字default来标注,被default所标注的方法,需要提供实现,而子类可以选择实现或者不实现该方法

然后在dto2do方法上,通过以下注解方式即可实现类型的转换:

@Mapping(target = "address",expression = "java(homeAddressToString(dto2do.getAddress()))")

上面这种是自定义的类型转换,还有一些类型的转换是MapStruct本身就支持的,如String和Date之间的转换:

@Mapping(target = "birthday",dateFormat = "yyyy-MM-dd HH:mm:ss")@Mapping(target = "birthday",dateFormat = "yyyy-MM-dd HH:mm:ss")
5、MapStruct的性能

MapStruct在编译时生成bean映射,这确保了高性能,可以提前将问题反馈出来,也使得开发人员可以彻底的错误检查。
在代码中使用了很多MapStruct提供的注解,这使得在编译期,MapStruct就可以直接生成bean映射的代码,相当于MapStruct写了很多setter和getter。
如在代码中定义了以下一个Mapper

@Mapper
interface PersonConverter {PersonConverter INSTANCE = Mappers.getMapper(PersonConverter.class);@Mapping(source = "userName", target = "name")@Mapping(target = "address",expression = "java(homeAddressToString(dto2do.getAddress()))")@Mapping(target = "birthday",dateFormat = "yyyy-MM-dd HH:mm:ss")PersonDO dto2do(PersonDTO dto2do);default String homeAddressToString(HomeAddress address){return JSON.toJSONString(address);}
}

经过代码编译后,会自动生成一个PersonConverterImpl:

@Generated(value = "org.mapstruct.ap.MappingProcessor",date = "2020-08-09T12:58:41+0800",comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_181 (Oracle Corporation)"
)class PersonConverterImpl implements PersonConverter {@Overridepublic PersonDO dto2do(PersonDTO dto2do) {if ( dto2do == null ) {return null;}PersonDO personDO = new PersonDO();personDO.setName( dto2do.getUserName() );if ( dto2do.getAge() != null ) {personDO.setAge( dto2do.getAge() );}if ( dto2do.getGender() != null ) {personDO.setGender( dto2do.getGender().name() );}personDO.setAddress( homeAddressToString(dto2do.getAddress()) );return personDO;}
}

在运行期,对于bean进行映射的时候,就会直接调用PersonConverterImpl的dto2do方法,这样就没有什么特殊的事情要做了,只是在内存中进行set和get就可以了。因为在编译期做了很多事情,所以MapStruct在运行期的性能会很好,并且还有一个好处,那就是可以把问题的暴露提前到编译期。使得如果代码中字段映射有问题,那么应用就会无法编译,强制开发者要解决这个问题才行。

这篇关于Java MapStruct 字段映射工具类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/956598

相关文章

Spring WebClient从入门到精通

《SpringWebClient从入门到精通》本文详解SpringWebClient非阻塞响应式特性及优势,涵盖核心API、实战应用与性能优化,对比RestTemplate,为微服务通信提供高效解决... 目录一、WebClient 概述1.1 为什么选择 WebClient?1.2 WebClient 与

Java.lang.InterruptedException被中止异常的原因及解决方案

《Java.lang.InterruptedException被中止异常的原因及解决方案》Java.lang.InterruptedException是线程被中断时抛出的异常,用于协作停止执行,常见于... 目录报错问题报错原因解决方法Java.lang.InterruptedException 是 Jav

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)

《java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)》:本文主要介绍java中pdf模版填充表单踩坑的相关资料,OpenPDF、iText、PDFBox是三... 目录准备Pdf模版方法1:itextpdf7填充表单(1)加入依赖(2)代码(3)遇到的问题方法2:pd

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi

最新Spring Security的基于内存用户认证方式

《最新SpringSecurity的基于内存用户认证方式》本文讲解SpringSecurity内存认证配置,适用于开发、测试等场景,通过代码创建用户及权限管理,支持密码加密,虽简单但不持久化,生产环... 目录1. 前言2. 因何选择内存认证?3. 基础配置实战❶ 创建Spring Security配置文件

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原