【实用工具】MapStruct—性能无限接近原生手写的对象转换工具

news2024/11/19 7:49:29

文章目录

            • 优秀借鉴
    • 1、引入
    • 2、什么是MapStruct
      • 2.1、概述
      • 2.2、横向对比
      • 2.3、优势
    • 3、快速入门
      • 3.1、Maven
      • 3.2、POJO
      • 3.3、统一映射接口
      • 3.4、业务映射接口
      • 3.5、测试
      • 3.6、输出
    • 4、简单分析
    • 5、拓展使用

优秀借鉴
  1. What is a Data Transfer Object (DTO)?
  2. Java bean mappings, the easy way!
  3. Quick Guide to MapStruct
  4. MapStruct使用指南
  5. 12种 vo2dto 方法,就 BeanUtils.copyProperties 压测最拉胯

1、引入

随着微服务和分布式应用程序迅速占领开发领域,数据完整性和安全性比以往任何时候都更加重要。在这些松散耦合的系统之间,安全的通信渠道和有限的数据传输是最重要的。

大多数时候,终端用户或服务不需要访问模型中的全部数据,而只需要访问某些特定的部分,而数据传输对象(Data Transfer Objects, DTO)经常被用于这些应用中,不仅为了减少网络传输的负担,也可充当防污的角色在系统服务中。

对于DTO的含义借鉴了Stack Overflow上面的答案:DTO就是一种用于封装数据并将其从应用程序的一个子系统发送到另一个子系统的对象。

多层应用程序在不同的对象模型之间编写映射代码是一项乏味且容易出错的事情,这时就需要用到对象转换工具进行辅助开发,而市面上有许多这类对象转换的工具将其余类转换成我们需要的DTO,除了我们所熟悉的Apache和Spring,还有许多其它类型的对象转换工具,接下来将简单对比多种工具并选取MapStruct进行介绍。

2、什么是MapStruct

2.1、概述

MapStruct 是一个代码生成器,用于创建实现Java Bean之间转换的扩展映射器,它基于约定优于配置的方法极大地简化了 Java bean 之间映射的实现,我们只需要创建接口,MapStruct就会在编译时自动创建一个具体的实现进行对象的转换。

MapStruct 旨在通过尽可能自动化来简化这项工作。与其他映射框架相比,MapStruct 在编译时生成 bean 映射,这确保了高性能,允许快速的开发人员反馈和彻底的错误检查。

2.2、横向对比

在市场上的工具类五花八门,这里引用小傅哥的测试数据进行展示。用于对象属性转换有12种,包括:普通的getset、json2Json、Apache属性拷贝、Spring属性拷贝、bean-mapping、bean-mapping-asm、BeanCopier、Orika、Dozer、ModelMapper、JMapper、MapStruct,分别测试这12种属性转换操作分别在一百次、一千次、一万次、十万次、一百万次时候的性能时间对比。

横向对比

  • BeanUtils.copyProperties 是大家代码里最常出现的工具类,但只要你不把它用错成 Apache 包下的,而是使用 Spring 提供的,就基本还不会对性能造成多大影响。
  • 但如果说性能更好,可替代手动get、set的,还是 MapStruct 更好用,因为它本身就是在编译期生成get、set代码,和我们写get、set一样。
  • 其他一些组件包主要基于 AOPASMCGlib,的技术手段实现的,所以也会有相应的性能损耗。

2.3、优势

在对比之后,选择MapStruct的理由如下:

  1. 配置灵活:MapStruct支持通过配置文件或注解来定义映射规则。开发人员可以根据具体需求选择更适合的配置方式。
  2. 集成简单:MapStruct可以与Spring、CDI等常用的Java框架无缝集成。它与其他框架的兼容性良好,使用起来非常方便。
  3. 性能优越:MapStruct通过在编译时生成映射代码,避免了运行时的反射操作,从而提升了映射的性能。它生成的映射代码非常高效,可以满足大部分应用场景的性能需求。

3、快速入门

3.1、Maven

<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.4.2.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct-processor -->
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.4.2.Final</version>
</dependency>

3.2、POJO

public class Person {
    private String name;
    private int age;
}

public class PersonDTO {
    private String fullName;
    private int yearsOld;
}

3.3、统一映射接口

这一步主要是为了增加拓展性,可去掉

@MapperConfig
public interface IMapping<SOURCE, TARGET> {

    /**
     * @description 映射同名属性
     * @author xbaozi
     * @date 2023/6/27 16:39
     * @param var1      源
     * @return TARGET   结果
     **/
    @Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
    TARGET sourceToTarget(SOURCE var1);

    /**
     * @description 映射同名属性,反向
     * @author xbaozi
     * @date 2023/6/27 16:40
     * @param var1      源
     * @return SOURCE   结果
     **/
    @InheritInverseConfiguration(name = "sourceToTarget")
    SOURCE targetToSource(TARGET var1);
    
}

3.4、业务映射接口

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE, unmappedSourcePolicy = ReportingPolicy.IGNORE)
public interface PersonMapper extends IMapping<Person, PersonDTO> {

    PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);

    @Mapping(source = "name", target = "fullName")
    @Mapping(source = "age", target = "yearsOld")
    @Override
    PersonDTO sourceToTarget(Person person);

    @Override
    Person targetToSource(PersonDTO personDTO);
}

3.5、测试

public class Main {
    public static void main(String[] args) {
        Person person = new Person("xbaoziplus", 18);

        PersonDTO personDTO = PersonMapper.INSTANCE.personToPersonDTO(person);

        System.out.println(personDTO.getFullName());
        System.out.println(personDTO.getYearsOld());
    }
}

3.6、输出

xbaoziplus
18

4、简单分析

前面有说到我们只需要创建映射接口,MapStruct就会在编译时自动创建一个具体的实现进行对象的转换。那么如果想要看到具体的实现该在哪里进行查看呢?其实只要我们进行 mvn clean install 命令之后,就可以在 /target/ generated-sources/annotations/ 路径下找到MapStruct在编译时为我们生成的实现类:

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE, unmappedSourcePolicy = ReportingPolicy.IGNORE)
public class PersonMapperImpl implements PersonMapper {

    @Override
    public PersonDTO personToPersonDTO(Person person) {
        if ( person == null ) {
            return null;
        }

        PersonDTO personDTO = new PersonDTO();

        personDTO.setFullName( person.getName() );
        personDTO.setYearsOld( person.getAge() );

        return personDTO;
    }

    @Override
    public Person personDTOToPerson(PersonDTO personDTO) {
        if ( personDTO == null ) {
            return null;
        }

        Person person = new Person();

        person.setName( personDTO.getFullName() );
        person.setAge( personDTO.getYearsOld() );

        return person;
    }
}

5、拓展使用

在MapStruct中还有许多的使用方式,不如集合的拷贝、流的拷贝等,这类拓展使用大家可以参考Quick Guide to MapStruct进行阅读使用。

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

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

相关文章

多元回归预测 | Matlab北方苍鹰算法(NGO)优化极限学习机ELM回归预测,NGO-ELM回归预测,多变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab北方苍鹰算法(NGO)优化极限学习机ELM回归预测,NGO-ELM回归预测,多变量输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码 %% 清…

HTTP模式下STM32程序远程升级设计

针对嵌入式终端设备架设分散、数量庞大以及应用程序更新迭代速度快带来的程序升级困难局面&#xff0c;运用STM32微控制器的在应用中编程&#xff08;IAP&#xff09;原理&#xff0c;设计了通过以太网远程升级程序的方案。 HTTP协议和LwIP协议的使用&#xff0c;不仅让整个方…

安装mmdetection2.22(windows下)

安装mmdetection2.22 确定版本安装mmcv1.4安装mmdetection测试方案1方案2 确定版本 安装mmcv1.4 首先.cuda,pytorch得安装好&#xff0c;这里我拷贝pt1.8虚拟环境 安装mmcv1.4 安装mmdetection 参考文章 下载 cd E:\Code\mmdetection\mmdetection-2.22.0 pip install -r…

机械臂笛卡尔空间轨迹规划

目录 1 引言 2 任务位置规划 2.1直线轨迹规划 2.2圆弧轨迹规划 (1)进行第一个步骤&#xff1a; (2) 进行第二步骤&#xff1a; &#xff08;3&#xff09;进行第三个步骤&#xff1a; &#xff08;4&#xff09;进行第四个步骤&#xff1a; 1 引言 随着6R机械人的使用…

设备通过ehome接入到EasyCVR后,通道数量显示不全是什么原因?

EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等&#xff0c;以及厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等&#xff0c;能对外分发RTSP、RTMP、FLV、HLS、WebRTC等格式的视频流。 有用…

【LeetCode】HOT 100(19)

题单介绍&#xff1a; 精选 100 道力扣&#xff08;LeetCode&#xff09;上最热门的题目&#xff0c;适合初识算法与数据结构的新手和想要在短时间内高效提升的人&#xff0c;熟练掌握这 100 道题&#xff0c;你就已经具备了在代码世界通行的基本能力。 目录 题单介绍&#…

linux修改oracle sys密码

忘记了sys密码 su - oracle&#xff1b; sqlplus / as sysdba; alter user system identified by test; navicat测试连接

【软件测试三】测试用例篇

目录 1.测试用例的基本要素 2.测试用例的给我们带来的好处 3.设计测试用例的万能公式 3.1.水杯的测试用例 3.2.微信发送朋友圈的测试用例 4.设计测试用例的方法 基于需求设计的测试用例 1.等价类 2.边界值 3.判定表 4.正交法 1.正交表表达式 2.特点&#xff1a; …

【OSI体系结构】网络杂谈(14)之OSI体系结构精准理解

涉及知识点 什么是OSI体系结构&#xff0c;OSI体系结构的概念&#xff0c;网络协议三要素&#xff0c;应用层&#xff0c;表示层&#xff0c;会话层&#xff0c;传输层&#xff0c;表示层&#xff0c;数据链路层&#xff0c;物理层&#xff0c;开放系统互连参考模型各层的功能…

CRM系统助力医疗机构数字化营销全链路,让获客和留存更简单

在数字经济背景下&#xff0c;医疗行业面临经营、管理、组织变革升级的迫切需求。伴随云计算、大数据、物联网、5G、人工智能等数字化技术的创新应用&#xff0c;加速推动了国内医疗机构数字化转型地落地。后疫情时代下&#xff0c;如何展望未来、寻找医疗健康行业重回增长轨道…

原生DOM与组件绑定 原生DOM事件和自定义事件

1. 原生DOM可以绑定原生DOM系统事件 2. 组件标签可以绑定系统事件&#xff08;不起作用&#xff0c;因为属于自定义事件&#xff09;------ .native &#xff08;可以把自定义事件变为原生DOM事件&#xff09; 3. 原生DOM绑定自定义事件 ---无意义&#xff1a;因为没有办法触…

企业部署MES管理系统需要配置专业团队吗

随着数字化转型的推进&#xff0c;越来越多的企业开始考虑部署MES生产管理系统来提高生产效率和管理水平。在部署制造企业MES系统时&#xff0c;是否需要配置专业团队是一个关键问题。本文将探讨企业部署MES管理系统所需的专业团队的重要性&#xff0c;并提供一些建议。 全球制…

微服务进阶篇

文章目录 1、SpringCloud面试快速答法 1.1、Eureka1.2、Nacos面试快速答法 1.3、Ribbon负载小总结面试快速答法 1.4、服务雪崩小总结面试快速答法 1.5、服务监控小总结面试快速答法 2、业务相关2.1、限流Nginx限流网关限流小总结面试快速答法 2.2、分布式事务分布式理论CAP、BA…

WEB漏洞-XXEXML之利用检测绕过全解(39)

#概念 xml&#xff1a;xml被设计成传输和储存数据&#xff0c;XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素&#xff0c;其焦点是数据的内容。就类似于一种数据的格式&#xff0c;代码类的一些东西&#xff1b; xxe&#xff1a;是xml上面的一个漏洞&#xff0c;…

STM32F407 基本定时器配置输出PWM方波

介绍STM32F407定时器PWM波形输出配置方式。 通过逻辑分析采集波形数据进行可视化显示对比。 【1】定时器PWM功能介绍 STM32F4 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也…

Vmware 虚拟机win7不识别usb3.0/3.1解决方案

问题现象&#xff1a; VMware安装的Win7系统&#xff0c;虚拟机设置USB控制器已打开&#xff0c;可以识别USB2.0U盘&#xff0c;不识别USB3.0/3.1U盘( 本人使用的金士顿U3.1)。 尝试方案&#xff1a; 1&#xff1a;检查本机系统Vmware USB 服务是否开启&#xff0c;重启虚拟机…

基于Ant DesignPro Vue + SpringBoot 前后端分离 - 后端微服化 + 接口网关 + Nacos + Sentinel

基于Ant DesignPro Vue SpringBoot 前后端分离 - 后端微服化 接口网关 Nacos Sentinel 通过Ant DesignPro Vue SpringBoot 搭建的后台管理系统后&#xff0c;实现了前后端分离&#xff0c;并实现了登录认证&#xff0c;认证成功后返回该用户相应权限范围内可见的菜单。 后…

小白也能学会!人物百度百科怎么创建?5分钟教会你怎么创建人物百度百科

在当今互联网的时代&#xff0c;越来越多的小伙伴都有了打造个人IP意识&#xff0c;把个人形象展示出来&#xff0c;形成一张网络名片。人物百度百科就是是我们一个不错的选择&#xff0c;它具有体面和象征性。大家都知道在搜索引擎上随便搜索一个明星的名字&#xff0c;都可以…

【Servlet学习五】实现一个简单的数据库版本的留言墙!

目录 一、前期环境搭建 二、具体后端代码实现 &#x1f308;1、创建数据库 &#x1f308;2、创建message类&#xff1a;定义属性和相应的get和set方法 &#x1f308;3、创建JDBC工具类&#xff1a;DBUtil文件&#xff0c;定义一些数据库的基本操作 &#x1f308;4、创建m…

【doxygen】doxygen 支持宏判断

文章目录 配置 doxygen代码中判断宏 配置 doxygen 定义自己的宏 HAL_CONFIG_USB 代码中判断宏 if HAL_CONFIG_USB your contents endif需要注意的是 Doxygen不支持直接的 elif 指令。Doxygen只提供了 if 和 endif 指令来实现条件性文档生成。如果您需要多个条件进行判断&am…