Java中常见的对象转换工具

作者:阿Qoder 时间:2023-12-14 19:23:16 

前言

我们在写搬砖的过程中,少不了需要将A对象转成B对象,对对象进行对象的转换是一个操作重复且繁琐的工作。于是市面上就有许多的对象转换工具来解决这个问题,下面我们就来看看几个比较常用的工具(mapstruct,Spring BeanUtils,Apache BeanUtils)使用方式及其性能 。

用法介绍

mapstruct

mapstruct基于注解+字节码生成的方式使用和运行。其支持的功能全面,运行时速度也很快(直接生成转换器类字节码)。示例如下:

maven依赖

<dependency>
   <groupId>org.mapstruct</groupId>
   <artifactId>mapstruct</artifactId>
   <version>1.4.2.Final</version>
</dependency>
<dependency>
   <groupId>org.mapstruct</groupId>
   <artifactId>mapstruct-jdk8</artifactId>
   <version>1.4.2.Final</version>
</dependency>
<dependency>
   <groupId>org.mapstruct</groupId>
   <artifactId>mapstruct-processor</artifactId>
   <version>1.4.2.Final</version>
   <scope>provided</scope>
</dependency>
  • mapstruct:MapStruct的核心库,包含了MapStruct的基本功能和API。

  • mapstruct-jdk8:MapStruct的扩展库,包含了对Java 8新特性的支持,例如对LocalDate、LocalTime、LocalDateTime等类型的映射。

  • mapstruct-processor:MapStruct的注解处理器,用于在编译时生成映射代码。

使用介绍

@Mapper
public interface UserMapper {
   UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

@Mapping(source = "name", target = "fullName")
   UserVO toUserVO(User user);

List<UserVO> toUserVOs(List<User> users);
}

@Data
public static class UserVO {
   private String fullName;
   private int    age;
}

@Data
public static class User {
   private String name;
   private int    age;
}

// 使用
UserVO userVO = UserMapper.INSTANCE.toUserVO(new User("", ""));
List<UserVO> userVOs = UserMapper.INSTANCE.toUserVOs(users);

如示例所示,

  • 我们只需要定义一个转换器接口,并标记注解@Mapper 。

  • UserMapper INSTANCE 添加一个调用单例对象。

  • UserVO toUserVO(User user); 书写转换方法,当两者的属性名称不一致时,可以添加@Mapping 注解来配置对应关系。

  • 其也可以支持列表的转换,这可以说是相当的方便了。

  • 查看反编译的源码,可以看到他对null是有检测了,我们也不怕转换的过程中出现空指针异常了。

  • @Mapping(target = "creationDate", expression = "java(new java.util.Date())") 。我们可以这样,去给一个对象设置默认值。

  • UserVO toUserVO(User user, Dep dep); 我们还可以将多个对象的值同时拷贝赋值到一个对象中。原理和单对象复制一样。

多源示例代码:

@Mapping(source = "person.description", target = "description")
@Mapping(source = "address.houseNo", target = "houseNumber")
DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address);

插件工具

我们可以在idea的插件市场搜索 【MapStruct support】插件,可以增强MapStruct的使用体验。

Java中常见的对象转换工具

Spring BeanUtils

Spring BeanUtils使用简单,其有几下几个特点:

  • 支持类型转换:BeanUtils可以自动将源对象属性的类型转换为目标对象属性的类型,例如将字符串类型的属性值转换为整数类型。

  • 支持批量复制:BeanUtils可以同时复制多个JavaBean对象的属性,从而简化复制操作。

  • 支持忽略属性:BeanUtils可以忽略某些属性的复制,从而减少不必要的复制操作。

  • 为了提高性能,spring缓存了PropertyDescriptor,以提高对象转换的速度。

  • 不支持属性名称不一致的拷贝,这一点需要注意下,需要拷贝属性了之后,自行处理一下。

示例代码:

org.springframework.beans.BeanUtils.copyProperties(user, userVO);

Apache BeanUtils

Apache BeanUtils和Spring BeanUtils使用方式差不多,唯一需要注意的是:Apache BeanUtils的目标类在前面,这一点和Spring BeanUtils正好相反。其特性和Spring BeanUtils差不多。不同点是:

  • 不支持忽略属性配置。

  • 未缓存Class配置,从效率来说,如果复制的对象比较多,效率奇差。从后文的【性能分析】中可以看出。

示例代码:

BeanUtils.copyProperties(userVO, user);

性能分析

下面附上mapstruct,Spring BeanUtils,Apache BeanUtils转换对象时时长运行截图:

1条数据下的测试情况:

Java中常见的对象转换工具

10条数据下的测试情况:

Java中常见的对象转换工具

100条数据下的测试情况:

Java中常见的对象转换工具

1000条数据下的测试情况:

Java中常见的对象转换工具

10000条数据下的测试情况:

Java中常见的对象转换工具


mapstructSpring BeanUtilsApache BeanUtils
12ms198ms53ms
102ms326ms199ms
1003ms277ms1236ms
10004ms636ms5320ms
1000015ms629ms39843ms

从上图中我们可以看出(以上数据仅供参考,更精确的测试可以使用JMH进行)。

  • mapstruct 表现稳定,性能最高,这和它的实现方式有关。

  • Spring BeanUtils 次之,性能也比较稳定,但是小数据量下性能不显著。

  • Apache BeanUtils 最差,性能随着数据量的增长而快速增长。在大数据量下千万别用。

来源:https://juejin.cn/post/7225186082312405048

标签:Java,对象,转换工具
0
投稿

猜你喜欢

  • java实现摄像头截图功能

    2023-12-01 19:53:22
  • Android仿IOS UIAlertView对话框

    2023-09-28 09:00:12
  • Android双向选择控件DoubleSeekBar使用详解

    2022-02-13 10:05:29
  • Mybatis的mapper.xml中if标签test判断的用法说明

    2023-12-23 23:04:16
  • c#多线程网络聊天程序代码分享(服务器端和客户端)

    2022-08-10 00:32:48
  • C#端口扫描器的编写方法

    2023-12-17 17:47:24
  • MyBatisPlus代码生成器的使用示例

    2022-04-28 07:52:42
  • Android实现手机震动效果

    2022-11-05 12:20:43
  • C#的编码规范详细说明

    2022-01-13 10:07:43
  • 从字符串中截取等长字节的Java代码

    2023-03-12 10:11:41
  • Java线程通信之wait-notify通信方式详解

    2022-05-17 19:35:46
  • C#中Span相关的性能优化建议

    2021-07-05 15:42:26
  • springboot2.3 整合mybatis-plus 高级功能(图文详解)

    2022-10-19 20:04:05
  • 详解Java编程中包package的内容与包对象的规范

    2022-03-06 17:48:08
  • C#中的多线程多参数传递详解

    2023-08-02 22:23:46
  • 使用代理模式来进行C#设计模式开发的基础教程

    2023-06-08 17:01:56
  • Spring七大事务传递机制深入分析实现原理

    2022-12-21 16:28:37
  • Java中的内存泄露问题和解决办法

    2022-05-12 20:02:35
  • ios百度地图的使用(普通定位、反地理编码)

    2023-07-03 15:26:17
  • c# 服务器上传木马监控代码(包含可疑文件)

    2022-07-08 10:02:45
  • asp之家 软件编程 m.aspxhome.com