MapStruct的优点
首先,我们了解下常见的转换对象方法:
// 1. getter+setter 这种方式会产生大量无意义工作和重复代码
// 2. BeanUtils 这种方式适用处理简单结构的转换,遇到字段名称不对应等情况,仍需要额外的处理
BeanUtils.copyProperties(Object source,Object target)
MapStruct特点
• 简单、自动化
• 编译时生成映射,确保运行时性能
• 只需要创建接口,大大减少样板代码的编码工作
MapStruct的使用
1. 引包与配置
<properties>
<org.mapstruct.version>1.4.1.Final</org.mapstruct.version>
</properties>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
*最新maven版本:https://mvnrepository.com/artifact/org.mapstruct/mapstruct
2. 编码及基本使用
先看下需要转换的两个类,这里简化模型,仅仅以VO及DO做为案例:
@Data
publicclass UserVO{
privateLong id;
privateString userName;
privateString email;
privateInteger gender;
}
@Data
@TableName(value ="User")
publicclass User implementsSerializable{
privatestaticfinallong serialVersionUID =1L;
@TableId(type = IdType.AUTO)
privateLong id;
privateString name;
privateString email;
privateString createdDate;
privateString updatedDate;
privateInteger gender;
}
第一步:下面是新建一个转换类的接口:
/**
* UserTransfer
*
* @author CaiHao
*@since 2022/3/1011:42
*/
// 标记为映射接口,@Mapper允许接口mapstruct-processor在编译期启动
@Mapper
publicinterface UserTransfer {
UserTransfer INSTANCE = Mappers.getMapper(UserTransfer.class);
// 映射名称不同的字段
@Mapping(source ="userName", target ="name")
// 声明转换方法
User toDo(UserVO vo);
@Mapping(source ="name", target ="userName")
UserVO toVo(User user);
// list转换
List<User>toDo(List<UserVO> voList);
List<UserVO>toVo(List<User> doList);
}
第二步:如何使用
// 方式一:通过INSTANCE实现访问
User user = UserTransfer.INSTANCE.toDo(tom);
或使用@Mapper(componentModel = "spring")
// 方式二:注入UserTransfer userTransfer;
User user = userTransfer.toDo(tom);
3. 拓展应用
情况一:变量为实体(嵌套bean)
@Data
@Builder
@AllArgsConstructor
publicclass EmployeeVO {
privateLong id;
privateString empName;
privateString gender;
private Contact contact;
}
@Data
publicclass Contact {
privateString address;
privateString phone;
privateString email;
}
@Data
@Builder
publicclass UserVO {
privateLong id;
privateString userName;
privateString email;
privateInteger gender;
privateString address;
privateString phone;
}
@Mapper
publicinterface UserTransfer {
UserTransfer INSTANCE = Mappers.getMapper(UserTransfer.class);
/**
* UserVO转换成EmployeeVO
*
* @param userVO userVO
*@return EmployeeVO EmployeeVO
*/
@Mapping(source ="userName", target ="empName")
@Mapping(source ="email", target ="contact.email")
@Mapping(source ="address", target ="contact.address")
@Mapping(source ="phone", target ="contact.phone")
EmployeeVO toEmployeeVO(UserVO userVO);
}
EmployeeVO employeeVO = UserTransfer.INSTANCE.toEmployeeVO(tom);
情况二: 类型转换、映射合成
publicclass User{
privateString updatedDate;
privateInteger gender;
}
publicclass UserVO {
privateDate gmtCreate;
privateString gender;
}
@Mappings({
@Mapping(target ="gender", expression="java(java.lang.String.valueOf(user.getGender()))"),
@Mapping(source ="createdDate", target ="gmtCreate", dateFormat ="yyyy-MM-dd HH:mm")
})
UserVO toVo(User user);
mapstruct的应用场景广泛,如转换、处理第三方服务结果集,同时配合Lombok注解,可以发挥出更好的效果。
*关于更多高级属性和方法,可以查看官方文档