前语

咱们在写搬砖的过程中,少不了需求将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>
  1. mapstruct:MapStruct的中心库,包含了MapStruct的基本功用和API。
  2. mapstruct-jdk8:MapStruct的扩展库,包含了对Java 8新特性的支撑,例如对LocalDate、LocalTime、LocalDateTime等类型的映射。
  3. 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);

如示例所示,

  1. 咱们只需求定义一个转化器接口,并标记注解@Mapper 。
  2. UserMapper INSTANCE 增加一个调用单例方针。
  3. UserVO toUserVO(User user); 书写转化办法,当两者的特点名称不一致时,能够增加@Mapping 注解来装备对应关系。
  4. 其也能够支撑列表的转化,这能够说是适当的方便了。
  5. 查看反编译的源码,能够看到他对null是有检测了,咱们也不怕转化的过程中出现空指针异常了。
  6. @Mapping(target = “creationDate”, expression = “java(new java.util.Date())”) 。咱们能够这样,去给一个方针设置默认值。
  7. 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运用简略,其有几下几个特点:

  1. 支撑类型转化:BeanUtils能够自动将源方针特点的类型转化为方针方针特点的类型,例如将字符串类型的特点值转化为整数类型。
  2. 支撑批量仿制:BeanUtils能够一起仿制多个JavaBean方针的特点,然后简化仿制操作。
  3. 支撑疏忽特点:BeanUtils能够疏忽某些特点的仿制,然后削减不必要的仿制操作。
  4. 为了进步功用,spring缓存了PropertyDescriptor,以进步方针转化的速度。
  5. 不支撑特点名称不一致的仿制,这一点需求注意下,需求仿制特点了之后,自行处理一下。

示例代码:

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中常见的对象转换工具

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 最差,功用跟着数据量的增加而快速增加。在大数据量下千万别用。

总结

一般咱们简略的特点仿制用Spring BeanUtils 就能够了,如果数据量比较大或许特点仿制的逻辑关系比较复杂,咱们能够用mapstruct完成功用。一般不建议运用Apache BeanUtils。