Bean 之间复制属性工具
BeanUtils
出自 Spring 的工具类, 使用也非常方便
方法定义
public static void copyProperties(Object source, Object target) throws BeansException {
copyProperties(source, target, null, (String[]) null);
}
最常见使用方法, 第一个参数为源对象(提供内容的对象), 第二个参数为目标对象 (需要填充的对象)
BeanUtils.copyProperties(cooperativeDo, cooperativeRes);
查看源码会发现大量的使用了反射
优缺点
- 使用非常简单方便
- 只能 copy 属性名相同的值
- 对于属性名不同的对象直接产生隐藏 bug, 不好排查.
- 由于大量使用反射, 性能低
MapStruct
官网地址
比较好教程
比较火的属性复制工具, 和 Lombok 的实现原理相同. 利用编译期解析注解, 生成转换的 setter 方法.
最简单的使用方式, 定义一个 接口, 用 @Mapper
标记
@Mapper
public interface PersonMapper {
PersonMapper INSTANCT = Mappers.getMapper(PersonMapper.class);
@Mapping(target = "name", source = "personName")
@Mapping(target = "id", ignore = true) // 忽略id,不进行映射
PersonDTO conver(Person person);
}
在 方法上可以自定义部分映射规则
使用方式
PersonDTO dto = PersonMapper.INSTANCT.conver(person);
将 Person
转为 PersonDTO
,
Person
的name
对应PersonDTO
的personName
- 忽略掉 id 属性
- 其他属性名相同的一一对应
优缺点
-
最终生成 setter 方法, 性能高
-
每次都需要声明一个 接口 文件
-
如果有 嵌套类, 属性名不一致的类, 需要大量定制
-
Debug 不方便
MapStruct Spring Extensions
官方指南
GitHub 地址
比较好的教程
MapStruct 结合 Spring framework 提供的 Converter<S,T>
接口, 可以将 生成的 转换类注入到 Ioc 容器中. 使用的时候直接 自动注入, 更方便.
最简单的使用方式
定义一个接口, 继承自 Converter, @Mapper(componentModel = "spring")
只能使用 Spring 模式
@Mapper(componentModel = "spring")
public interface CarMapper extends Converter<Car, CarDto> {
@Mapping(target = "seats", source = "seatConfiguration")
CarDto convert(Car car);
}
使用时直接自动注入 ConversionService
, 使用所有的映射器是, 都只需要注入 ConversionService
@Autowired
private ConversionService conversionService;
Car car = ……;
CarDto carDto = conversionService.convert(car,CarDto.class);
优缺点
-
同 MapStruct , 性能高
-
还是需要编写接口文件
-
统一注入
ConversionService
类型, 好记
mapstruct-spring-plus
GitHub 地址
作者博客
MapStruct Spring Extensions 的 改进型
最简单的使用方式
@Data
@AutoMap(targetType = Car.class)
public class CarDto {
private String make;
@AutoMapField(target = "carType")
private String type;
}
@Data
public class Car {
private String make;
private String carType;
}
@Autowired
private IObjectMapper mapper;
Car entity = mapper.map(dto, Car.class);
优缺点
- 原理同 MapStruct , 性能高
- 不需要接口 文件
- 统一使用
IObjectMapper
类型
BeanMappingKey
GitHub 地址
作者博客
这是个 IDEA 的插件, 直接通过插件市场搜索 BeanMappingKey
安装即可.
使用方式也很简单, 选中方法后直接右击 → BeanMappingKey
优缺点
- 性能高
- 方便调试
- 不能直接生成的, 方便修改
总结
- 对于性能要求不高, 而且两个类中大部分都是相同属性的, 推荐
BeanUtils
- 对于使用 Spring 框架的, 有性能要求的推荐使用 MapStruct Spring Extensions 和 mapstruct-spring-plus, 因为 MapStruct Spring Extensions 是官方工具, 稳定性高, mapstruct-spring-plus 使用方便, 但是个人开源, 可能存在 bug 修复不及时
- 对于复杂的嵌套对象, 没法直接映射的, 推荐使用
BeanMappingKey