Java对象属性拷贝组件——对象映射器Object mapping

技术的更新很快,曾经几何时,还在纠结数据库连接池是c3p0还是dbcp,反复测试哪个更快。再到后来BoneCP、Druid出世,Druid占据了配置里好长时间。现如今,HikariCP秒杀了一切。充分体现了技术人员孜孜不倦的对性能和效率追求,是没有终点的。

Java的Bean对象属性拷贝的是个很小的功能点,一直以来都是BeanUtil的copyProperties,无论是用的commmons-utils还是spring包里的。

目前这领域的技术叫做映射器(Object mapping),技术分成两类:

1、使用反射技术调用拿到属性的set/get方法通过invoke赋值 。 这类的代表:commons-beanutilsDozerModelMaper

2、编译期动态生成调用set/get代码的class文件。 这类的代表:MapStructSelmaOrika

使用反射技术实现的对象拷贝和使用动态编译生成字节码的技术,性能上不具可比性,基本是被吊打。
下面是一张来自网上性能测试对比图,每秒操作数,越高越好,Manual是手工set/get的指标。
在这里插入图片描述
使用上来说,动态生成字节码,编写调用时,必须有个stub,一般会要求先编写一个接口,在这个基础上做一些属性映射上的设置。目前推荐的是MapStruct这个库,虽然Selma这个有着更为接近手写set的拷贝性能,但是考虑到它的项目已经好多年未更新了。

可以看一下官网首页的样例代码:

先定义映射器接口:

@Mapper
public interface CarMapper {
 
    CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );
 
    @Mapping(source = "numberOfSeats", target = "seatCount")
    CarDto carToCarDto(Car car);
}

然后使用它拷贝指定的bean:

@Test
public void shouldMapCarToDto() {
    //given
    Car car = new Car( "Morris", 5, CarType.SEDAN );
 
    //when
    CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );
 
    //then
    assertThat( carDto ).isNotNull();
    assertThat( carDto.getMake() ).isEqualTo( "Morris" );
    assertThat( carDto.getSeatCount() ).isEqualTo( 5 );
    assertThat( carDto.getType() ).isEqualTo( "SEDAN" );
}

看起来,精准、安全、高效。但我估计用起来会有点累。都动态生成代码了,还非得写一个接口是干嘛。

期待更好的方案。如果不考虑性能,我还是会使用BeanUtil,那样更轻松些。

附:

五种常见Bean映射工具的性能比对

推荐一个 Java 实体映射工具 MapStruct

对象拷贝 - 优雅的解决方案 Mapstruct

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值