展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

MapStruct使用(一)

  • 官网

  • 不同的convert解决方案

名字 描述
mapstruct 基于jsr269实现在编译期间生成代码,性能高,精细控制,解耦
orika 能够精细控制,解耦
org.springframework.beans.BeanUtils体系 简单易用,不能对属性进行定制处理
  • 自己编写conver,需写大量的代码
    /**
     * 测试传统的通过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对象
     */
    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;
    }
  • 使用MapStruct转换
# 引入依赖
    <dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct</artifactId>
      <version>${mapstruct.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct-processor</artifactId>
      <version>${mapstruct.version}</version>
    </dependency>

# 编写convert
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public abstract class CarConvert {

    public static CarConvert INSTANCE = Mappers.getMapper(CarConvert.class);

    public abstract CarVO dto2vo(CarDTO carDTO);

}

# 测试
    @Test
    public void test2() {
        CarDTO carDTO = buildCarDTO();
        CarVO carVO = CarConvert.INSTANCE.dto2vo(carDTO);
        System.out.println(carVO);
    }
  • 默认映射规则
同类型且同名的属性,会自动映射

mapstruct会自动进行类型转换
  8种基本类型和他们对应的包装类
  8种基本类型(含包装类)和string之间
  日期类型和string
  • @Mappings和@Mapping
指定属性之间的映射关系
  数字格式化:numberFormat = "#.00"
  日期格式化:dateFormat = "yyyy-MM-dd HH:mm:ss"

source或target多余的属性对方没有,不会报错的

ignore
  源属性不想映射到目标属性,使用该配置,目标属性显示null

属性是引用对象的映射处理
  @Mapping(source = "driverDTO",target = "driverVO") // 并写上对应的abstract方法

  @Mapping(source = "id",target = "driverId")
  @Mapping(source = "name",target = "fullName")
  public abstract DriverVO driverDTO2DriverVO(DriverDTO driverDTO);

@AfterMapping和@MappingTarget
  在映射最后一步对属性的自定义映射处理
  • 完整代码
@Mapper
public abstract class CarConvert {

    public static CarConvert INSTANCE = Mappers.getMapper(CarConvert.class);

    /**
     * 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
     */
    @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);
    }

}
posted @ 2022-10-02 21:47  DogLeftover  阅读(102)  评论(0编辑  收藏  举报