本文共 3970 字,大约阅读时间需要 13 分钟。
MapStruct是满足JSR269规范的一个Java注解处理器,用于为Java Bean生成类型安全且高性能的映射。它基于编译阶段生成get/set代码,此实现过程中没有反射,不会造成额外的性能损失。
为使用MapStruct,需要引入:
org.mapstruct mapstruct-jdk8 1.2.0.Final org.mapstruct mapstruct-processor 1.2.0.Final
要使用MapStruct,需要通过接口进行注入。
ClassLoader方式加载:
@Mapperpublic interface ApiMapper { ApiMapper INSTANCE = Mappers.getMapper(ApiMapper.class);}
spring注入:
@Mapper(componentModel = "spring")public interface ApiMapper { }
Bean类型映射时,按照:
以一个用户请求到用户数据的转换为例进行说明:
通过@Builder
和@AllArgsConstructor
可方便定义用于Bean初始化的builder接口。
用户请求中会携带一个token,只是用于校验,不会转换到目标用户数据:
@Data@Builder@NoArgsConstructor@AllArgsConstructorpublic class UserRequest implements Serializable { private static final long serialVersionUID = 1L; private String token; private String name; private String idNo; private String sex; private String phone;}
目标用户数据中id是数据库中的唯一信息,不会从请求中获取(转换时默认为null):
import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;@Data@Builder@NoArgsConstructor@AllArgsConstructorpublic class UserData { private Integer id; private String name; private String certNo; private Integer sex; private String phone;}
对于certNo,因其与request中的idNo名称不同,需要使用Mapping来指定;而sex类型不同,且有转换规则,所以定义了静态函数用于转换,并通过Mapping中expression指定(里面的函数必须是全名称的)。若定义好了类的转换,则对应的集合(如List)转换接口会自动处理好类型转换。
通过@MappingTarget
可以更新已有的Bean。
@Mapperpublic interface Request2Data { Request2Data Instance = Mappers.getMapper(Request2Data.class); @Mapping(source = "idNo", target = "certNo") @Mapping(target = "sex", expression = "java(com.example.study.component.mapst.Request2Data.convertSex(req.getSex()))") UserData request2Data(UserRequest req); // 自动使用request2Data来转换每个元素 Listrequest2DataList(List lstReq); // 此时source中需要指定具体用的是哪个参数;UserData中id由nId参数设定 @Mapping(source = "req.idNo", target = "certNo") @Mapping(source = "nId", target = "id") @Mapping(target = "sex", expression = "java(com.example.study.component.mapst.Request2Data.convertSex(req.getSex()))") UserData request2Data(UserRequest req, Integer nId); @Mapping(source = "idNo", target = "certNo") @Mapping(target = "sex", expression = "java(com.example.study.component.mapst.Request2Data.convertSex(req.getSex()))") void updateUser(UserRequest req, @MappingTarget UserData user); static Integer convertSex(String sex){ final List Female = Arrays.asList("F", "f", "female", "Female"); if(Female.contains(sex)) return 0; return 1; }}
通过以下测试代码,测试其转换:
@GetMapping("hello") public void userTest(){ UserRequest reqUser = UserRequest.builder() .token("token") .name("name") .idNo("371321123456") .sex("F") .phone("135123456") .build(); _logger.info("Request: {}", reqUser); UserData user = Request2Data.Instance.request2Data(reqUser); // UserData(id=null, name=name, certNo=371321123456, sex=0, phone=135123456) _logger.info("User: {}", user); UserData user2 = Request2Data.Instance.request2Data(reqUser, 15); // UserData(id=15, name=name, certNo=371321123456, sex=0, phone=135123456) _logger.info("User2: {}", user2); // update user UserData userUpdate = UserData.builder() .id(10) .sex(1) .build(); Request2Data.Instance.updateUser(reqUser, userUpdate); // UserData(id=10, name=name, certNo=371321123456, sex=0, phone=135123456) _logger.info("Update: {}", userUpdate); }
转载地址:http://czilf.baihongyu.com/