【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 略低在编译时生成的代码(像编译后生成的默认实现类中存在指定的业务代码),因此性能较高,映射过程效率优秀。
依赖可直接使用,实现简单需要手动添加依赖引入,定义额外的处理过程

 

📫四、章末

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

        文章到这里就结束了~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

先锋 Coder

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

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

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

打赏作者

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

抵扣说明:

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

余额充值