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的使用体验。
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条数据下的测试情况:
10条数据下的测试情况:
100条数据下的测试情况:
1000条数据下的测试情况:
10000条数据下的测试情况:
mapstruct | Spring BeanUtils | Apache BeanUtils | |
---|---|---|---|
1 | 2ms | 198ms | 53ms |
10 | 2ms | 326ms | 199ms |
100 | 3ms | 277ms | 1236ms |
1000 | 4ms | 636ms | 5320ms |
10000 | 15ms | 629ms | 39843ms |
从上图中我们可以看出(以上数据仅供参考,更精确的测试可以使用JMH进行)。
mapstruct 表现稳定,性能最高,这和它的实现方式有关。
Spring BeanUtils 次之,性能也比较稳定,但是小数据量下性能不显著。
Apache BeanUtils 最差,性能随着数据量的增长而快速增长。在大数据量下千万别用。
来源:https://juejin.cn/post/7225186082312405048


猜你喜欢
- 给Word文档设置背景时,通常只能针对整篇文档设置统一的背景,如果需要对某些页面单独设置背景,则需要通过另外的方式来实现。本文通过C# 程序
- 1. 增强for概述增强for循环,也叫Foreach循环,用于数组和容器(集合类)的遍历。使用foreach循环遍历数组和集合元素时,无需
- 本文实例为大家分享了java微信公众号支付示例代码,供大家参考,具体内容如下开始之前,先准备好:appid、商家号、商户密匙。工具类:MD5
- session失效时间 在Tomcat上,session的默认有效时间是30分钟。也可以通过配置文件修改session的有效时间。
- 概述Handler是Android消息机制的上层接口。通过它可以轻松地将一个任务切换到Handler所在的线程中去执行。通常情况下,Hand
- 概念在Java中,对象的生命周期包括以下几个阶段:创建阶段(Created)应用阶段(In Use)不可见阶段(Invisible)不可达阶
- 一、搭建 mvc 环境新建一个 module 模块,创建 maven 工程,步骤跟以前一样,各种配置文件内容也可以拷贝修改一下即可。二、创建
- 前言MyBatis常用标签及标签使用技巧MyBatis的常用标签有很多,比如<sql id="">:预定义可
- SelectMany操作符提供了将多个from子句组合起来的功能,相当于数据库中的多表连接查询,它将每个对象的结果合并成单个序列。示例:st
- java中synchronized(同步代码块和同步方法)详解及区别问题的由来:看到这样一个面试题://下列两个方法有什么区别p
- 背景知识Fluent Interface是一种通过连续的方法调用以完成特定逻辑处理的API实现方式,在代码中引入Fluent Interfa
- 概要设计模式是一门艺术,如果真正了解这门艺术,你会发现,世界都将变得更加优美。定义定义一个用于创建对象的接口,让其子类去决定实例化那个类使用
- android提供的工具链和开发工具比较完善,因此它的开发环境的搭建比较简单,相信许多朋友都已经搭建好环境,并编写了HelloA
- 循环结构分两大类,一类是当型,一类是直到型。当型:当布尔值表达式条件为True时,反复执行某语句,当布尔表达式的值为False时才停止循环,
- /// <summary> /// 删除掉空
- 如执行:"2|33|4".split("|")出来的结果是:""2334奇怪吧,
- 1.使用keySet进行遍历实现步骤:(1)使用Map集合中的方法keySet(),把Map集合所有的key取出来,存储到一个Set集合中(
- 这篇文章主要介绍了springboot配置文件绑定实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要
- SpringBoot 整合RabbitMq 自定义消息监听容器来实现消息批量处理前言RabbitMQ是一种常用的消息队列,Spring Bo
- ObjectMapper 忽略字段大小写核心代码:ObjectMapper mapper = new ObjectMapper();mapp