官方文档:https://mapstruct.org/documentation/dev/reference/html/
1.场景介绍
2.为什么要用框架?
- 复杂而多的业务逻辑,不能突出业务的重点
- 重复的劳动,代码无法复用
3.使用介绍
3.1引入POM
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.2.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.4.2.Final</version>
</dependency>
3.2新建抽象类并标注@Mapper
@Mapper
public interface UserConvert
3.3编写转换方法
/**
* userDTO->UserVO
*/
UserVO dto2vo(UserDTO userDTO);
3.4动态获取Convert实例
public UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
3.5测试
UserDO userDO = UserDO.builder()
.id(1)
.username("maofeiyu")
.authorities(Arrays.asList("123", "455", "4343"))
.createTime(LocalDateTime.now())
.updateTime(LocalDateTime.now())
.version(1).build();
System.out.println(JSON.toJSONString(userDO, true));
UserDTO userDTO = UserConvert.INSTANCE.do2dto(userDO);
System.out.println(JSON.toJSONString(userDTO, true));
4.高级配置
4.1@Mapper
默认映射规则
- 同类型,同名的属性会自动映射
自动类型转换
- 8种基本数据类型和他们的包装类型会自动进行转换
- 8种基本数据类型和String之间会自动进行转换
- 日期类型和String之间会自动转换
4.2@Mappings和@Mapping
- 指定属性之间的映射关系
- 数字格式化 numberFormat = “#.00”
- 日期格式化 dateFormat = “yyyy-MM-dd HH:mm:ss”
- source或者target多余的属性不会报错
- ignore忽略属性映射(需要自己手动赋值)
- 属性是引用的处理(需要在同一个类中配置引用类型的转换处理)
- 批量映射(需要先指定单一映射)
4.3案例
4.3.1基本类型转换配置
@Mappings(
value = {
/**
* @param source-源属性名
* @param target-转换对象属性名
* @param numberFormat-数字格式化规则
*/
@Mapping(
source = "totalPrice",
target = "totalPrice",
numberFormat = "#.00"
),
/**
* @param source-源属性名
* @param target-转换对象属性名
* @param dateFormat-日期格式化规则
*/
@Mapping(
source = "publishDate",
target = "publishDate",
dateFormat = "yyyy-MM-dd HH:mm:ss"
),
/**
* @param target-忽略的目标属性
*/
@Mapping(target = "color", ignore = true),
@Mapping(source = "driverDTO", target = "driverVO"),
}
)
4.3.2引用类型配置转换
@Mappings(
value = {
@Mapping(source = "id", target = "id"),
@Mapping(source = "name", target = "fullname")
}
)
UserVO userDTO2userVO(UserDTO userDTO);
4.4批量转换
原始方法:for循环进行便利添加 优化做法:使用stream流进行遍历 高级做法:使用mapStruct进行批量转换
/**
* 批量转换
*/
abstract List<UserVO> dto2vos(List<UserDTO> carDTO);
5.高级注解
5.1@AfterMapping和@MappingTarget自定义属性
在映射的最后一步,进行
自定义属性
的映射处理场景:两种完全不同的类型需要映射(自定义映射)
/**
* 描述: 表示让mapstruct在调用完自动转换方法之后,会自动调用本方法
* 自定义属性映射处理
*/
@AfterMapping
public void dto2voafter(UserDTO userDTO, @MappingTarget UserVO userVO) {
// @MappingTarget 标识当前传递过来的target对象是已经赋值过得
// 手动获取属性进行判断,并赋值
List<UserDTO> partDTOs = userDTO.getPartDTOs();
boolean hasPartDTOs = partDTOs != null && !partDTOs.isEmpty();
userVO.setHasPart(hasPartDTOs);
}
5.2@BeanMapping
忽略默认映射行为,避免不需要的赋值,避免属性覆盖
场景:我们在映射的过程中,target类拥有很多的属性,但是只有几个属性需要我们
自动映射
,其他属性需要手动进行设置
原始的方式: 通过@Mapping的方式来ignore来进行忽略(但是如果有非常多的属性不适合使用)
/**
* 配置忽略mapStruct的默认映射行为,只映射那些@Mapping的属性
*/
@BeanMapping(ignoreByDefault = true)
@Mapping(source = "id", target = "id")
abstract UserVO userdto2uservo(UserDTO userDTO);
5.3@InheritConfiguration
- 更新的场景
5.4@InheritInverseConfiguration
- 反向反射过来不用重新写一次
只集成@Mapping注解配置,不会集成@BeanMapping
6.SpringBoot整合
注入Bean到Spring容器中
@Mapper(componentModel="spring") 本质:给生成的类添加了一个@Component注解