public class UserConverter { public static UserDTO toDTO(UserDO userDO) { UserDTO userDTO = new UserDTO(); userDTO.setAge(userDO.getAge()); // 问题 1: 自己赋值给自己 userDTO.setName(userDTO.getName()); return userDTO; } @Data public static class UserDO { private String name; private Integer age; // 问题 2: 新增字段未赋值 private String address; } @Data public static class UserDTO { private String name; private Integer age; } }反例2:
public class UserBeanCopyConvert { public UserDTO toDTO(UserDO userDO) { UserDTO userDTO = new UserDTO(); // 堆代码 duidaima.com // 用反射复制不同类型对象. // 1. 重构不友好, 当我要删除或修改 UserDO 的字段时, 无法得知该字段是否通过反射被其他字段依赖 BeanUtils.copyProperties(userDO, userDTO); return userDTO; } }使用 Mapstruct
@Mapper( componentModel = "spring", unmappedSourcePolicy = ReportingPolicy.ERROR, unmappedTargetPolicy = ReportingPolicy.ERROR, // convert 逻辑依赖 DateUtil 做日期转化 uses = DateUtil.class ) public interface UserConvertor { UserDTO toUserDTO(UserDO userDO); @Data class UserDO { private String name; private Integer age; //private String address; private Date birthDay; } @Data class UserDTO { private String name; private Integer age; private String birthDay; } } public class DateUtil { public static String format(Date date) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); return simpleDateFormat.format(date); } }使用示例:
@RequiredArgsConstructor @Component public class UserService { private final UserDao userDao; private final UserCovertor userCovertor; public UserDTO getUser(String userId){ UserDO userDO = userDao.getById(userId); return userCovertor.toUserDTO(userDO); } }
编译期校验:
生成的代码:
@Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2023-12-18T20:17:00+0800", comments = "version: 1.3.1.Final, compiler: javac, environment: Java 11.0.12 (GraalVM Community)" ) @Component public class UserConvertorImpl implements UserConvertor { @Override public UserDTO toUserDTO(UserDO userDO) { if ( userDO == null ) { return null; } UserDTO userDTO = new UserDTO(); userDTO.setName( userDO.getName() ); userDTO.setAge( userDO.getAge() ); userDTO.setBirthDay( DateUtil.format( userDO.getBirthDay() ) ); return userDTO; } }