【Java Bean 映射器】通过 MapStruct 和 BeanUtils 拷贝对象的区别

目录

👋前言

👀一、环境准备

🌱二、拷贝工具使用

        2.1 BeanUtils 使用

        2.2 MapStruct 使用

💞️三、对比

📫四、章末


👋前言

        小伙伴们大家好,最近在一些技术文章中看到了开发时经常接触的对象拷贝操作,实现该操作的话有很多方式,来探讨下常见的对象拷贝工具:MapStruct 和 Apache Commons BeanUtils

有哪些使用差异和哪些特性

👀一、环境准备

        为了方便对比每种拷贝工具的使用,先创建好几个基础类

        TestData.class 填充数据类,代码如下:

import lombok.Data;

@Data
public class TestData {
    private Integer id;
    public TestData(int i){
        this.id = i;
    }
}

        Source.class 代表源数据类,代码如下:

import lombok.Data;

/**
 * @author HuangBen 
 */
@Data
public class Source {
    private Integer id;
    private String name;
    private TestData data;
    private Long createTime;
}

        Target.class 代表目标数据类,代码如下: 

@Data
public class Target {
    private Long id;
    private String name;
    private TestData data;
    private Long createTime;
}

🌱二、拷贝工具使用

        2.1 BeanUtils 使用

        BeanUtils 的使用比较简单,如下,先创建一个填充对象 testData(用于测试拷贝中涉及到的对象拷贝是深拷贝还是浅拷贝) ,然后创建源数据类,以及一个空的 target 对象,通过 BeanUtils.copyProperties(Source.class,Target.class) 方法将源数据类中的属性赋值给目标类对象:

        拷贝后的结果如下,可以看到目标类中 Long 类型的 id 与源数据 Integer 类型的 id 拷贝出现 null 值,另外对于 testData 的拷贝属于浅拷贝类型:

注:浅拷贝简单来讲就是拷贝出来的对象依然指向原有对象的引用地址,所以两者 == 操作的时候返回 true,并且修改原有对象会一并影响拷贝对象

        深拷贝出来的对象与原先对象没有联系,== 操作为 false,并且修改原有对象不会影响拷贝出来的对象

         2.2 MapStruct 使用

                2.2.1 mapStruct 是一个外部工具需要在 pom.xml 文件中手动导入依赖(版本可替换)

        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>1.2.0.Final</version>
        </dependency>

                2.2.2 定义工具接口

                这里注意 @Mapper 注解的来源是 mapstruct 包下,不是 mybatis 的注解

                另外一个方法就是自定义的对象拷贝方法,从 Source 转换为 Target ,使用方式如下,该方式不需要提前创建对象,因为转换方法有返回值

import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

/**
 * @author HuangBen 
 */
@Mapper
public interface BeanMapper {

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

  Target map(Source source);

}

 

        拷贝结果如下,可以看到从 Integer 类型转换为 long 类型的时候,mapstruct 会自动进行类型转换处理,并且默认也是浅拷贝:

               

                 2.2.3  MapStruct 不同类型转换成功分析

                测试类编译后我们可以在target目录下找到帮我们生成的一个接口实现类BeanMapperImpl,如下:

                在默认提供的实现类中会对不同类型的元素进行手动转换(前提支持这种类型转换)

 

💞️三、对比

BeanUtilsMapStruct
作用域属于运行时的工具库,使用反射机制动态地操作 Java Bean 的属性,存在性能开销基于编译时注解处理器的工具,在编译阶段生成映射代码,因此映射过程是类型安全的,并且在运行时性能较高。
性能使用反射机制来进行属性复制,运行时性能比 MapStruct 略低在编译时生成的代码(像编译后生成的默认实现类中存在指定的业务代码),因此性能较高,映射过程效率优秀。
依赖可直接使用,实现简单需要手动添加依赖引入,定义额外的处理过程

 

📫四、章末

        文中这种使用方式只是简单的对象拷贝操作,更多功能可以参考官方文档

        文章到这里就结束了~

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
MapStructBeanUtilsJava中常用的对象映射工具,它们都可以用于将一个对象的值映射到另一个对象上。以下是它们的优缺点: MapStruct的优点: 1. 性能优秀:MapStruct在编译期间生成映射代码,相比运行时的反射机制,具有更好的性能表现。 2. 类型安全:MapStruct在编译期间进行类型检查,避免了在运行时可能出现的类型转换错误。 3. 易于使用:MapStruct通过注解配置简单明了,生成的映射代码也易于理解和维护。 MapStruct的缺点: 1. 学习曲线较陡:对于初学者来说,需要一定时间去了解和掌握MapStruct的使用方式和配置方式。 2. 配置复杂:对于复杂的映射场景,可能需要编写自定义的转换或者使用复杂的配置方式。 BeanUtils的优点: 1. 简单易用:BeanUtils提供了简单的API,易于学习和使用。 2. 动态性:BeanUtils使用反射机制,在运行时可以动态地进行属性复制。 BeanUtils的缺点: 1. 性能较差:由于使用了反射机制,BeanUtils在属性复制过程中性能相对较低,特别是处理大量对象时会有明显的性能损耗。 2. 不支持类型安全:BeanUtils在属性复制时没有类型检查,容易出现类型转换错误。 综上所述,MapStruct在性能和类型安全方面具有优势,适用于需要高性能和类型安全的场景。而BeanUtils则更适用于简单的属性复制场景,对于性能要求不高且不涉及复杂类型转换的情况下使用较为方便。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

先锋 Coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值