一、mapstruct简介
-
官网 :
MapStruct – Java bean mappings, the easy way!
二、mapstruct的使用
2.1 不使用框架的缺点
- 多而杂的代码与业务逻辑耦合,不能==突出业务逻辑的重点==
- 重复的劳动
2.2 @Mapper
-
默认映射规则
-
同类型且同名的属性,会自动映射
-
mapstruct会自动进行类型转换
- 8种基本类型和他们对应的包装类
- 8种基本类型(含包装类)和string之间
- 日期类型和string
-
2.3 @Mappings和@Mapping
-
指定属性之间的映射关系
- 日期格式化:dateFormat = "yyyy-MM-dd HH:mm:ss"
- 数字格式化:numberFormat = "#.00"
-
source或target多余的属性对方没有,不会报错的
-
ignore
-
属性是引用对象的映射处理
@Mapping(source = "driverDTO",target = "driverVO") // 并写上对应的abstract方法
-
批量映射
2.4 @AfterMapping和@MappingTarget
- 在映射最后一步对属性的自定义映射处理
2.5 @BeanMapping
- ignoreByDefault : 忽略mapstruct的默认映射行为。避免不需要的赋值、避免属性覆盖
2.6 @InheritConfiguration
- 更新的场景,避免同样的配置写多份
2.7 @InheritInverseConfiguration
2反向映射不用反过来再写一遍,==注意:只继承@Mapping注解配置,不会继承@BeanMapping==
2.8 测试代码:
-
@SpringBootTest public class MapStructTest { @Resource private CarConvert carConvert; /** * 测试mapstruct和spring整合 */ @Test public void test7() { VehicleVO vehicleVO = new VehicleVO(); vehicleVO.setId(9999L); vehicleVO.setBrandName("别克"); vehicleVO.setPrice(66554322d); CarDTO carDTO = carConvert.vehicleVO2CarDTO(vehicleVO); System.out.println(carDTO); } /** * 测试@InheritInverseConfiguration反向继承 */ @Test public void test6() { VehicleVO vehicleVO = new VehicleVO(); vehicleVO.setId(9999L); vehicleVO.setBrandName("别克"); vehicleVO.setPrice(66554322d); CarDTO carDTO = CarConvert.INSTANCE.vehicleVO2CarDTO(vehicleVO); System.out.println(carDTO); } /** * 测试@InheritConfiguration继承配置 */ @Test public void test5() { CarDTO carDTO = buildCarDTO(); VehicleVO vehicleVO = CarConvert.INSTANCE.carDTO2vehicleVO(carDTO); CarDTO carDTO2 = new CarDTO(); carDTO2.setId(330L); carDTO2.setPrice(789d); carDTO2.setBrand("迈巴赫"); // 通过carDTO2的属性值来更新已存在的vehicleVO对象 CarConvert.INSTANCE.updateVehicleVO(carDTO2,vehicleVO); System.out.println(vehicleVO); } /** * 测试@BeanMapping */ @Test public void test4() { CarDTO carDTO = buildCarDTO(); VehicleVO vehicleVO = CarConvert.INSTANCE.carDTO2vehicleVO(carDTO); System.out.println(vehicleVO); } /** * 测试mapstruct批量转换 * List<CarDto>--> List<CarVo> */ @Test public void test3() { CarDTO carDTO = buildCarDTO(); List<CarDTO> carDTOList = new ArrayList<>(); carDTOList.add(carDTO); // source // target List<CarVO> carVOList = CarConvert.INSTANCE.dtos2vos(carDTOList); System.out.println(carVOList); } /** * 测试mapstruct * CarDto-->CarVo */ @Test public void test2() { CarDTO carDTO = buildCarDTO(); CarVO carVO = CarConvert.INSTANCE.dto2vo(carDTO); System.out.println(carVO); } /** * 测试传统的通过getter和setter赋值完成pojo之间转换 * CarDto-->CarVo */ @Test public void test1() { // 模拟业务构造出的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 totalPriceStr = df.format(totalPrice); carVO.setTotalPrice(totalPriceStr); Date publishDate = carDTO.getPublishDate(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String publishDateFormat = sdf.format(publishDate); carVO.setPublishDate(publishDateFormat); 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); } /** * 模拟业务构造出的CarDTO对象 * @return */ private CarDTO buildCarDTO() { CarDTO carDTO = new CarDTO(); carDTO.setId(330L); carDTO.setVin("vin123456789"); carDTO.setPrice(123789.126d); carDTO.setTotalPrice(143789.126d); carDTO.setPublishDate(new Date()); carDTO.setColor("白色"); carDTO.setBrand("大众"); // 零件 PartDTO partDTO1 = new PartDTO(); partDTO1.setPartId(1L); partDTO1.setPartName("多功能方向盘"); PartDTO partDTO2 = new PartDTO(); partDTO2.setPartId(2L); partDTO2.setPartName("智能车门"); List<PartDTO> partDTOList = new ArrayList<>(); partDTOList.add(partDTO1); partDTOList.add(partDTO2); carDTO.setPartDTOS(partDTOList); // 设置驾驶员 DriverDTO driverDTO = new DriverDTO(); driverDTO.setId(88L); driverDTO.setName("小明"); carDTO.setDriverDTO(driverDTO); return carDTO; } }
@Mapper(componentModel = "spring") public abstract class CarConvert { public static CarConvert INSTANCE = Mappers.getMapper(CarConvert.class); // // @Autowired // private UserService userService; /** * CarDto-->CarVo */ @Mappings( value = { @Mapping(source = "totalPrice",target = "totalPrice",numberFormat = "#.00"), @Mapping(source = "publishDate",target = "publishDate",dateFormat = "yyyy-MM-dd HH:mm:ss"), @Mapping(target = "color",ignore = true), @Mapping(source = "brand",target = "brandName"), @Mapping(source = "driverDTO",target = "driverVO") } ) public abstract CarVO dto2vo(CarDTO carDTO); /** * driverDTO-->driverVO * @param driverDTO * @return */ @Mapping(source = "id",target = "driverId") @Mapping(source = "name",target = "fullName") public abstract DriverVO driverDTO2DriverVO(DriverDTO driverDTO); @AfterMapping // 表示让mapstruct在调用完自动转换的方法之后,会来自动调用本方法 public void dto2voAfter(CarDTO carDTO,@MappingTarget CarVO carVO) { // @MappingTarget : 表示传来的carVO对象是已经赋值过的 List<PartDTO> partDTOS = carDTO.getPartDTOS(); boolean hasPart = partDTOS != null && !partDTOS.isEmpty(); carVO.setHasPart(hasPart); } /** * dto2vo这个方法的批量转换 */ public abstract List<CarVO> dtos2vos(List<CarDTO> carDTO); /** * 配置忽略mapstruct的默认映射行为,只映射那些配置了@Mapping的属性 * @param carDTO * @return */ @BeanMapping(ignoreByDefault = true) @Mapping(source = "id",target = "id") @Mapping(source = "brand",target = "brandName") public abstract VehicleVO carDTO2vehicleVO(CarDTO carDTO); /** * 会继承全部配置,包括@BeanMapping和@Mapping * @param carDTO * @param vehicleVO */ @InheritConfiguration(name = "carDTO2vehicleVO") public abstract void updateVehicleVO(CarDTO carDTO,@MappingTarget VehicleVO vehicleVO); /** * 测试@InheritInverseConfiguration反向继承,只会继承@Mapping * 故需要再单独写一次 @BeanMapping * name:指定使用哪一个方法的配置,写方法的名字 * @param vehicleVO * @return */ @BeanMapping(ignoreByDefault = true) @InheritInverseConfiguration(name = "carDTO2vehicleVO") public abstract CarDTO vehicleVO2CarDTO(VehicleVO vehicleVO); }