一、mapstruct简介
-
官网:https://mapstruct.org/
-
使用场景:不同领域对象之间的转换,pojo之间的相互转化
-
不同的转换解决方案
名称 | 描述 |
---|---|
mapstruct | 基于jsr269实现在编译期间生成代码,性能高,精细控制,解耦 |
orika | 能够精细控制,解耦 |
org.springframework.beans.BeanUtils体系 | 简单易用,不能对属性进行定制处理 |
二、mapstruct使用
2.1 不使用框架的缺点
- 多而杂的代码与业务逻辑耦合
- 重复的劳动
2.2mapstruct spring集成
2.2.1Maven依赖
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.3.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct-processor -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.1.Final</version>
</dependency>
2.2.2基本使用
-
创建需要进行pojo接口/抽象类
-
/** * @author xianping * @description car相关的转换 * @date 2021年03月27日 18:43 */ @Mapper public interface CarConvert { /* * @description carDto转化carVo * @author xianping * @date 2021/3/27 19:03 * @param carDto * @return com.xianping.demo_mapstruct.vo.CarVo */ CarVo carDtoTOCarVo(CarDto carDto); }
-
-
添加
Mapper
注解org.mapstruct.Mapper
包下注解
-
测试
-
/* * @description 传统的对象转换模拟 * @author xianping * @date 2021/3/27 19:01 */ @Test void oldConvertTest() { //转化dto->vo CarDto carDTO = buildCarDTO(); CarVo carVO = new CarVo(); oldConvert(carDTO, carVO); System.out.println("carVO = " + carVO); } private CarDto buildCarDTO() { CarDto carDto = new CarDto(); carDto.setId(1L); carDto.setVin("123456789"); carDto.setPrice(90000); carDto.setTotalPrice(120000); carDto.setPublishDate(new Date()); carDto.setBrand("奔驰"); //零件 PartDTO partDTO1 = new PartDTO(); partDTO1.setPartId(1L); partDTO1.setPartName("多功能方向盘"); PartDTO partDTO2 = new PartDTO(); partDTO2.setPartId(2L); partDTO2.setPartName("智能车门"); carDto.setPartDTOS(List.of(partDTO1, partDTO2)); //司机 DriverDTO driverDTO = new DriverDTO(); driverDTO.setId(88L); driverDTO.setName("小明"); carDto.setDriverDTO(driverDTO); return carDto; }
-
@Mapper
- 默认映射规则
- 同类型且同名的属性,会自动映射
- mapstruct自动类型转换
- 基本类型和对应的包装类型之间会自动转换
- 基本类型包括他们的包装类型和String类型会自动转换
- 日期类型(不仅限于Date)和String之间会自动转换
@Mapper和@Mappings
-
@Mappings({ @Mapping(source = "totalPrice", target = "totalPrice", numberFormat = "#.00"), @Mapping(source = "publishDate", target = "publishDate", dateFormat = "yyyy-MM-dd HH:mm:ss"), @Mapping(target = "color", ignore = true) }) CarVo carDtoTOCarVo(CarDto carDto);
-
@Mapping(source = “ 转 换 来 源 实 体 字 段 名 " , t a r g e t = " {转换来源实体字段名}", target = " 转换来源实体字段名",target="{指定转换对象实体字段名}”, numberFormat = “#.00”)
-
numberFormat:数字类型格式化
-
dateFormat:日期格式化
-
ignore:忽略映射字段
source或target多于的属性对方没有,是不会产生错误的
属性为引用对象类型
-
新增指定的引用对象类型转换方法
-
/* * @description DriverDTO转DriverVO * @author xianping * @date 2021/3/27 21:53 * @param driverDTO * @return com.xianping.demo_mapstruct.vo.DriverVO */ @Mappings({ @Mapping(source = "id", target = "driverId"), @Mapping(source = "name", target = "fullName") }) DriverVO driverDTOToDriverVO(DriverDTO driverDTO);
-
-
@Mappings中配置引用对象类型转换
-
@Mapping(source = "driverDTO", target = "driverVo")
-
mapstruct会自动查找对应的转换方法进行调用转换
-
@AfterMapping和@MappingTarget
-
@AfterMapping
- 表示mapstruct在调用完自动转换的方法之后,会来自动调用本方法
-
@MappingTarget
- 表示传来的carVO对象是已经赋值过的
-
在映射最后一一步对属性的自定义映射处理
/*
* @description
* @author xianping
* @date 2021/3/27 22:04
* @param carDto
* @param carVo
*/
@AfterMapping
default void customFieldConvert(CarDto carDto, @MappingTarget CarVo carVo) {
carVo.setHasPart(!carDto.getPartDTOS().isEmpty());
}
批量映射(集合类型转换)
-
增加批量转换方法
-
/* * @description 集合类型批量转换 * @author xianping * @date 2021/3/27 22:16 * @param carDtos * @return java.util.List<com.xianping.demo_mapstruct.vo.CarVo> */ List<CarVo> carDtoBatchToCarVo(List<CarDto> carDtos);
-
-
mapstruct会自动实现该方法
@BeanMapping
-
ignoreByDefault:忽略mapstruct的默认映射行为。避免不需要的赋值、避免属性覆盖
-
配置忽略mapstruct的默认映射行为,只映射那些置了@Mapping的属性
-
/* * @description 配置忽略mapstruct默认映射行为,只映射那些配置了mapping的属性 * @author xianping * @date 2021/3/27 22:27 * @param driverDTO * @return com.xianping.demo_mapstruct.vo.VehicleVo */ @BeanMapping(ignoreByDefault = true) //@Mapping(source = "id", target = "id") VehicleVo ignoreCarDtoToVehicleVo(CarDto carDto);
@InheritConfiguration
-
属性更新,继承配置
-
更新的场景,避免同样的配置写多份
-
/* * @description 属性更新,继承配置 * @author xianping * @date 2021/3/27 22:50 * @param driverDTO * @param vehicleVo * @return com.xianping.demo_mapstruct.vo.VehicleVo */ @InheritConfiguration @Mapping(target = "id", ignore = true)//通过配置ignore达到某些属性不被覆盖 VehicleVo updateVehicleVo(DriverDTO driverDTO, @MappingTarget VehicleVo vehicleVo);
@InheritInverseConfiguration
- 反向映射不用反过来再写一遍,
- 注意:只继承@Mapping注解配置,不会继承@BeanMapping
与spring结合
//添加componentModel,实际编译后会添加@Component注解使spring识别
@Mapper(componentModel = "spring")