MapStruct
1.什么是MapStruct
简单来说,MapStruct 可以将某几种类型的对象映射为另外一种类型,如将多个 DO(业务实体对象) 对象转换为 DTO(数据传输对象),避免了在业务代码内new DTO对象和不断的进行set方法
2.如何使用MapStruct
(1)引入Maven依赖
<!--mapStruct依赖--> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-jdk8</artifactId> <version>1.2.0.Final</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <scope>provided</scope> <version>1.2.0.Final</version> </dependency>
(2)使用
此处假设将两个实体对象(StudentInfo,classInfo)转换为一个DTO(StudentInfoDTO)
@Data public class StudentInfo { /** * 姓名 */ private String siName; /** * 年龄 */ private Integer siAge; /** * 所属班级 */ private String siClassId; }
@Data public class classInfo { /** * 名称 */ private String ciName; /** * 别名 */ private String ciNickName; /** * 楼号 */ private String ciFloor; }
@Data public class StudentInfoDTO { /** * 姓名 */ private String name; /** * 年龄 */ private Integer age; /** * 班级名称 */ private String className; }
创建 Mapper(映射)接口,MapStruct 就会自动实现该接口
@Mapper public interface StudentInfoStruct { /** * get new mapStruct instance */ StudentInfoStruct INSTANCE = Mappers.getMapper(StudentInfoStruct.class); /** * 转换学生信息实体 * * @return */ @Mappings({ @Mapping(source = "studentInfo.siName", target = "name"), @Mapping(source = "studentInfo.siAge", target = "age"), @Mapping(source = "classInfo.ciName", target = "className"), }) StudentInfoDTO from(ClassInfo classInfo,StudentInfo studentInfo) ; }
业务层调用代码
classInfo,studentInfo实体 以通过逻辑实现获得
StudentInfoDTO studentInfoDTO = StudentInfoStruct.INSTANCE.from(classInfo,studentInfo);
单个实体对象转换DTO同理
(3)当转换过程中有逻辑实现时,如进行余额变动或传入单个参数过多,则需要定义的转换 抽象类
@Mapper public abstract class UserBalanceRecordStruct { /** * get new mapStruct instance */ public static UserBalanceRecordStruct INSTANCE = Mappers.getMapper(UserBalanceRecordStruct.class); /** * 转换余额变动记录 * * @param balanceId 余额账户编号 * @param changeBalance 本次余额变动金额 * @param changeTypeId 变动类型 * @param oldBalance 变动之前余额 * @param unifiedOrderNo 统一订单编号 * @return */ public BalanceRecordEntity from(String balanceId, BigDecimal changeBalance, String changeTypeId, BigDecimal oldBalance, String mark, String unifiedOrderNo) { BalanceRecordEntity recordEntity = new BalanceRecordEntity(); recordEntity.setUbrBalanceId(balanceId); recordEntity.setUbrChangeCount(changeBalance); recordEntity.setUbrTypeId(changeTypeId); recordEntity.setUbrChangeBefore(oldBalance); recordEntity.setUbrChangeAfter(oldBalance.add(changeBalance)); recordEntity.setUbrMark(mark); recordEntity.setUbrUnifiedNo(unifiedOrderNo); return recordEntity; } /** * 通过原始的记录请求参数实体转换为最新的分页查询记录的请求参数实体 * * @param param 账户变动记录查询实体 * @return */ // public abstract BalanceRecordSearchParam from(BalanceRecordListParam param,String logicId); }
3.MapStruct注解
- @Mapper:注解在接口、类上,这样 MapStruct 才会去实现该接口
- componentModel:该属性用于指定实现类的类型,有几个属性:
- default:默认,不使用任何组建类型,可以通过Mappers.getMapper(Class) 方式获取实例对象
- spring:在实现类上注解 @Component,可通过 @Autowired 方式注入
- jsr330:实现类上添加@javax.inject.Named 和@Singleton注解,可以通过 @Inject注解获取。
- componentModel:该属性用于指定实现类的类型,有几个属性:
- @Mappings:配置多个@Mapping 单个实体转换时,如字段一致,则不需要配置
- @Mapping:配置属性映射,若源对象属性与目标对象名字一致,会自动映射对应属性
- source:源属性、target:目标属性
- dateFormat:可将 String 到 Date 日期之间相互转换,通过 SimpleDateFormat,该值为 SimpleDateFormat 的日期格式