java代码简洁-mapstruct

功能介绍:

MapStruct是一个Java注释处理器,用于生成类型安全的bean映射类。简化各种对象的转换。
在这里插入图片描述

不使用框架:
1.多而杂得代码与业务逻辑耦合
2.重复的劳动力

mapstruct使用:

1.导入依赖

 <dependency>
       <groupId>org.mapstruct</groupId>
       <artifactId>mapstruct</artifactId>
      <version>1.3.1.Final</version>
</dependency>
<dependency>
       <groupId>org.mapstruct</groupId>
       <artifactId>mapstruct-processor</artifactId>
      <version>1.3.1.Final</version>
</dependency>
配合lombok
<dependency>
      <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
</dependency>

2.插件安装(非必须)–重启idea
在这里插入图片描述

实体类准备

汽车DTO对象

@Data
public class CarDTO {
    /**
     * 编号
     */
    private Long id;
    /**
     * 车辆编号
     */
    private String vin;
    /**
     * 裸车价格
     */
    private double price;
    /**
     * 上路价格
     */
    private double totalPrice;
    /**
     * 生产日期
     */
    private Date publishDate;
    /**
     * 品牌名称
     */
    private String brand;
    /**
     * 汽车包含零件列表
     */
    private List<PartDTO> partDTOS;
    /**
     * 骑车的司机
     */
    private DriverDTO driverDTO;

    /**
     * 车的颜色
     */
    private String color;

}

驾驶员DTO对象

@Data
public class DriverDTO {
    /**
     * id
     */
    private Long id;
    /**
     * 驾驶员名称
     */
    private String name;
}

汽车零件DTO对象

@Data
public class PartDTO {
    /**
     * 汽车零件id
     */
    private Long partId;
    /**
     * 汽车零件名字
     */
    private String partName;
}

汽车VO对象

@Data
public class CarVO {
    /**
     * 编号
     */
    private Long id;
    /**
     * 车辆编号
     */
    private String vin;
    /**
     * 裸车价格
     */
    private double price;
    /**
     * 上路价格,保留两位小数
     */
    private String totalPrice;
    /**
     * 生产日期
     */
    private String publishDate;
    /**
     * 品牌名称
     */
    private String brandName;
    /**
     * 汽车是否包含零件
     */
    private Boolean hasPart;
    /**
     * 骑车的司机
     */
    private DriverVO driverVO;

    /**
     * 车的颜色
     */
    private String color;
}

驾驶员VO对象

@Data
public class DriverVO {
    /**
     * 驾驶员id
     */
    private Long driverId;
    /**
     * 驾驶员名称
     */
    private String fullName;
}

零件VO对象

@Data
public class PartVO {
    /**
     * 汽车零件id
     */
    private Long partId;
    /**
     * 零件名字
     */
    private String partName;
}

模拟业务构造出的carDTO对象

 private CarDTO buildCarDTO() {
    CarDTO carDTO = new CarDTO();
    carDTO.setId(330L);
    carDTO.setVin("vin12345698");
    carDTO.setPrice(123789.685);
    carDTO.setTotalPrice(145698.665);
    carDTO.setPublishDate(new Date());
    PartDTO partDTO1 = new PartDTO();
    partDTO1.setPartId(1L);
    partDTO1.setPartName("多功能方向盘");
    PartDTO partDTO2 = new PartDTO();
    partDTO2.setPartId(2L);
    partDTO2.setPartName("智能车门");
    ArrayList<PartDTO> list = new ArrayList<>();
    list.add(partDTO1); list.add(partDTO2);
    carDTO.setPartDTOS(list);
    DriverDTO driverDTO = new DriverDTO();
    driverDTO.setId(2L);
    driverDTO.setName("哇哈");
    carDTO.setDriverDTO(driverDTO);
    carDTO.setColor("白色");
    carDTO.setBrand("品牌");
    return carDTO;
  }

1.默认映射规则

1.1创建一个抽象类或接口并标注@Mapper注解

import org.mapstruct.Mapper;

@Mapper
public abstract class CarConvert {
	//获取对象INSTANCE并使用
    public static CarConvert INSTANCE = Mappers.getMapper(CarConvert.class);
    //转换方法
     public abstract CarVO dto2vo(CarDTO carDTO);
 }

1.2测试

 @Test
    public void test2() {
        CarDTO carDTO = buildCarDTO();
        CarVO carConvert = CarConvert.INSTANCE.dto2vo(carDTO);
        System.out.println(carConvert);
    }

1.3结果输出

CarVO(id=330, vin=vin12345698, price=123789.685, totalPrice=145698.665, publishDate=22-8-4 上午11:33, brandName=null, hasPart=true, driverVO=null, color=白色)
默认映射规则:
1.同类型,同名的属性会自动映射
2.自动类型转换
2.1基本类型和包装类型会自动转换,
2.28种基本类型(及包装类型)和String
2.3日期类型和String

2.@Mappings指定某个属性的映射规则

1.抽象接口上加@Mappings注解

//source和target多余的属性对方没有,不会报错
//source映射源属性,target目标映射属性
//numberFormat = "#.00" 数字格式化,保留两位小数
//dateFormat = "yyy-MM-dd HH:mm:ss" 日期格式化
//ignore=true 不映射该属性
 @Mappings(value = {
            @Mapping(source = "totalPrice", target = "totalPrice", numberFormat = "#.00"),
            @Mapping(source = "publishDate", target = "publishDate", dateFormat = "yyy-MM-dd HH:mm:ss"),
            @Mapping(target = "color", ignore=true),
            @Mapping(source = "brand",target = "brandName"),//属性名称不一样,也可以匹配
            @Mapping(source = "driverDTO",target = "driverVO")//对象转化,通过driverDTO2DriverVO方法实现
    })
 public abstract CarVO dto2vo(CarDTO carDTO);

2.也可以单独写@Mapping

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

3.@AfterMapping在映射的最后一步对属性进行自定义映射处理

  @AfterMapping //表示mapstruct在调用完自动转换的方法后,会来自动调用本方法
  //@MappingTarget 表示传来的carVO对象是已经赋值过的
  public void dat2voAfter(CarDTO carDTO,@MappingTarget CarVO carVO){
      List<PartDTO> partDTOS = carDTO.getPartDTOS();
      //判断零件集合是否为空,给carVo设置值
      boolean hasPart = partDTOS != null && !partDTOS.isEmpty();
      carVO.setHasPart(hasPart);
 }

测试如上,结果打印

测试如上,结果打印
CarVO(id=330, vin=vin12345698, price=123789.685, totalPrice=145698.67, publishDate=2022-08-04 14:11:11, brandName=品牌, hasPart=true, driverVO=DriverVO(driverId=2, fullName=哇哈), color=白色)

4.批量转换

抽象方法
public abstract List<CarVO> dtos2vos(List<CarDTO> carDTOS);

测试

 @Test
    public void test3() {
        CarDTO carDTO = buildCarDTO();
        List<CarDTO> carDTOList = new ArrayList<>();
        carDTOList.add(carDTO); //source
        List<CarVO> carVOS = CarConvert.INSTANCE.dtos2vos(carDTOList);
        System.out.println(carVOS);
    }

5. @BeanMappring

配置忽略mapstruct的默认映射行为,只映射了Mapping的属性
汽车VO对象

@Data
public class VehicleVO {
    /**
     * 编号
     */
    private Long id;
    /**
     * 裸车的价格
     */
    private Double price;
    /**
     * 品牌
     */
    private String brandName;
}

抽象方法

  @BeanMapping(ignoreByDefault = true)
    @Mapping(source = "id",target = "id")
    @Mapping(source = "brand",target = "brandName")
    public abstract VehicleVO carDTO2vehicleVO(CarDTO carDTO);

测试类:

 @Test
    public void test4() {
        CarDTO carDTO = buildCarDTO();
        VehicleVO vehicleVO = CarConvert.INSTANCE.carDTO2vehicleVO(carDTO);
        System.out.println(vehicleVO);
        }
结果打印:
VehicleVO(id=330, price=null, brandName=品牌)

6.@InheritConfiguration避免同样配置写多份

抽象方法

1.借用之前抽象方法
   @BeanMapping(ignoreByDefault = true)
    @Mapping(source = "id",target = "id")
    @Mapping(source = "brand",target = "brandName")
    public abstract VehicleVO carDTO2vehicleVO(CarDTO carDTO);
2.利用@InheritConfiguration,继承配置,避免以上注解重复
    @InheritConfiguration  //避免同样的配置写多份
    /*@BeanMapping(ignoreByDefault = true)
      @Mapping(source = "id",target = "id")
      @Mapping(source = "brand",target = "brandName")*/
    @Mapping(target = "id",ignore = true)
    public abstract VehicleVO updateVehicleVO(CarDTO carDTO,@MappingTarget VehicleVO vehicleVO);

测试类

 @Test
    public void test4() {
        CarDTO carDTO = buildCarDTO();
        VehicleVO vehicleVO = CarConvert.INSTANCE.carDTO2vehicleVO(carDTO);
        System.out.println(vehicleVO);

        CarDTO carDTO2 = new CarDTO();
        //测试@InheritConfiguration继承配置
        //通过carDTO2的属性值来更新已存在的vehicleVO对象
         //brandName修改了,id被覆盖  VehicleVO(id=null, price=null, brandName=迈巴赫)
        carDTO2.setBrand("迈巴赫");
        VehicleVO updateVehicleVO = CarConvert.INSTANCE.updateVehicleVO(carDTO2, vehicleVO);
        System.out.println(updateVehicleVO);
    }
结果打印
VehicleVO(id=330, price=null, brandName=品牌)
VehicleVO(id=330, price=null, brandName=迈巴赫)

7.@InheritInverseConfiguration反向映射不需反过来再写一遍

只继承@Mapping注解,不继承@BeanMapring注解
抽象接口

    @BeanMapping(ignoreByDefault = true)
    @Mapping(source = "id",target = "id")
    @Mapping(source = "brand",target = "brandName")
    //VehicleVO(id=330, price=null, brandName=品牌)
    public abstract VehicleVO carDTO2vehicleVO(CarDTO carDTO);
    
反向继承 name指定用哪个方法 
    @InheritInverseConfiguration(name = "carDTO2vehicleVO")
    @BeanMapping(ignoreByDefault = true)
    public abstract CarDTO vehicleVO2carDTO(VehicleVO vehicleVO);

测试类

@Test
    public void test6() {
        VehicleVO vehicleVO = new VehicleVO();
        vehicleVO.setId(999L);
        vehicleVO.setBrandName("别克");
        vehicleVO.setPrice(65899544d);
        CarDTO dto = CarConvert.INSTANCE.vehicleVO2carDTO(vehicleVO);
        System.out.println(dto);
    }
    
结果打印:
CarDTO(id=999, vin=null, price=0.0, totalPrice=0.0, publishDate=null, brand=别克, partDTOS=null, driverDTO=null, color=null)

8.与spring整合

抽象类的@Mapper注解加上spring

import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public abstract class CarConvert {
	//获取对象INSTANCE并使用
    public static CarConvert INSTANCE = Mappers.getMapper(CarConvert.class);
    //转换方法
     public abstract CarVO dto2vo(CarDTO carDTO);
 }
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java MapStruct是一个代码生成器,用于处理Java bean之间的映射。它通过在编译时生成映射代码来提高性能,并且可以自定义映射逻辑。以下是使用Java MapStruct的步骤: 1. 添加MapStruct依赖项到Maven或Gradle项目中。 2. 创建一个Java接口,该接口定义了要映射的源和目标bean之间的映射方法。 3. 在接口上使用@Mapper注释,指定MapStruct生成的实现类的名称。 4. 在映射方法上使用@Mapping注释,指定源和目标bean属性之间的映射关系。 5. 在Maven或Gradle项目中运行编译命令,以生成MapStruct实现类。 6. 在代码中使用MapStruct生成的实现类来执行bean之间的映射。 下面是一个使用Java MapStruct的简单示例: 1. 添加MapStruct依赖项到Maven或Gradle项目中。 ```xml <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-jdk8</artifactId> <version>1.4.2.Final</version> </dependency> ``` 2. 创建一个Java接口,该接口定义了要映射的源和目标bean之间的映射方法。 ```java @Mapper public interface CarMapper { CarDto carToCarDto(Car car); } ``` 3. 在接口上使用@Mapper注释,指定MapStruct生成的实现类的名称。 ```java @Mapper(componentModel = "spring") public interface CarMapper { CarDto carToCarDto(Car car); } ``` 4. 在映射方法上使用@Mapping注释,指定源和目标bean属性之间的映射关系。 ```java @Mapper(componentModel = "spring") public interface CarMapper { @Mapping(source = "numberOfSeats", target = "seatCount") CarDto carToCarDto(Car car); } ``` 5. 在Maven或Gradle项目中运行编译命令,以生成MapStruct实现类。 6. 在代码中使用MapStruct生成的实现类来执行bean之间的映射。 ```java @Autowired private CarMapper carMapper; public void example() { Car car = new Car("Morris", 5); CarDto carDto = carMapper.carToCarDto(car); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值