MapStruct
使用场景:用于不同的pojo之间的转化
传统方式
通过get,set方式转换
@Data
publci class CarDTO{
private Long id;
private String name;
…
}
@Data
public class CarVO{
}
业务层代码如下:
//模拟业务构造出的CarDTO对象
CarDTO carDTO = buildCarDTO();
//转换dto-vo
CarVO carVO = new CarVO();
carVO.setId(carDTO.getId());
carVO.setVin(carDTO.getVin());
carVO.setPrice(carDTO.getPrice());
double totalPrice = carDTO.getTotalPrice();
DecimalFormat df = new DecimalFormat("#.00");
String format = df.format(totalPrice);
carVO.setTotalPrice(format);
Date publishDate = carDTO.getPublishDate();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format1 = sdf.format(publishDate);
carVO.setPublishDate(format1);
carVO.setBrandName(carDTO.getBrand());
List<PartDTO> partDTOS = carDTO.getPartDTOS();
boolean hasPart = partDTOS!=null&&partDTOS.isEmpty();
carVO.setHasPart(hasPart);
DriverVO driverVO = new DriverVO();
DriverDTO driverDTO = carDTO.getDriverDTO();
driverVO.setDriverId(driverDTO.getId());
driverVO.setFullName(driverDTO.getName());
carVO.setDriverVO(driverVO);
System.out.println(carVO);
很明显,非常复杂且不能突出业务逻辑的重点,并且是重复的劳动。
@Mapper
默认映射规则
- 同名且同类型的属性自动映射
- mapstrucet会自动类型转换:
1,8种基本类型和他们对应的包装类型之间会自动转换
2,8种基本类型(包括他们的包装类型)和String之间会自动转换
3,日期类型和String之间会自动转换
@Mappings和@Mapping
1,指定属性之间的映射关系
@Mappings(//source指映射源,target转换成的目标对象的名字
value = {
@Mapping(source = “totalPrice”,target = “totalPrice”,numberFormat = “#.00”),
@Mapping(source = “publishDate”,target = “publishDate”,dateFormat = “yyyy-MM-dd”),
}
)
public abstract CarVO abc(CarDTO carDTO);
2,source或target多余的属性对方没有,不会报错的
3,ignore
@Mapping(target = “color”,ignore = true) 两边都有,加了之后就不会映射
4,属性是引用对象的映射处理
@Mappings(//source指映射源,转换成的目标对象的名字
value = {
@Mapping(source = “totalPrice”,target = “totalPrice”,numberFormat = “#.00”),
@Mapping(source = “publishDate”,target = “publishDate”,dateFormat = “yyyy-MM-dd”),
@Mapping(target = “color”,ignore = true),
@Mapping(source = “brand”,target = “brandName”),
@Mapping(source = “driverDTO”,target = “driverVO”)//会调用下面的方法进行映射
})
public abstract CarVO abc(CarDTO carDTO);
@Mapping(source = “id”,target = “driverId”)
@Mapping(source = “name”,target = “fullName”)
public abstract DriverVO driverDTO2DriverVO(DriverDTO driverDTO);
}
5,@AfterMapping和MappingTarget
在映射的最后一步对属性的自定义映射处理
@AfterMapping//表示让mapstruct在调用完自动转换的方法之后,会来自动调用的方法
public void cardto2voAfter(CarDTO carDTO,@MappingTarget CarVO carVO);
//@MappingTarget表示传来的carVO对象是已经赋值过的
/*
* List< PartDTO> partDTOS = carDTO.getPartDTOS();
* boolean hasPart = partDTOS!=null&&partDTOS.isEmpty();
* carVO.setHasPart(hasPart);
* */
6,批量映射
/*
* 集合批量转换
* */
public abstract List< CarVO> dto2vos(List< CarDTO> carDTO);
List< CarVO> carVOS = CarConvert.INSTANCE.dto2vos(carDTOS);
7,@BeanMapping
ignoreByDefault:
//忽略mapstruct的默认映射行为,只映射那些配置了@Mapping的属性
@BeanMapping(ignoreByDefault = true)
@Mapping(source = “id”,target = “id”)
public abstract CarVO dto2vos(List carDTO);
8,@InheritConfiguration
更新的场景,避免同样的配置写多份
9,@InheritInverseConfiguration
反向映射,不用反过来再写一遍
//name指定使用哪一个方法的配置,写方法的名字
@InheritConfiguration(name = “dto2vos”)
public abstract CarDTO vo2dto(List carVOS);
注意,只继承@Mapping注解配置,不会继承@BeanMapping
10,与spring结合使用
@Mapper(componentModel = “spring”)
public interface CarConvert {
之后就可以用Autowired来注入CarConvert 。实质就是给生成的类加了@Component注解