使用MapStruct,让Bean对象之间转换更简单( 二 )


@Mapper(componentModel = "spring")public interface AddressMapper {AddressDTO toDto(Address address);}@Mapper(componentModel = "spring",uses = {AddressMapper.class})public interface StudentMapper {@Mapping(source = "gender", target = "sex")StudentDTO toDto(Student student);}自定义转换逻辑映射如果在对象转换时,不仅是简单的属性之间的映射,还需要按照某种业务逻辑进行转换,比如每个Student中的地址信息Address,在StudentDTO中只需要地址信息中的city 。
源对象类
@Datapublic class Student{private int no;private String name;private String gender;private Address address;}@Datapublic class Address{private String city;private String province;}目标对象类
@Datapublic class StudentDTO{private int no;private String name;private String sex;private String city;}针对这种情况,我们可以直接在source中使用address.city,也可以通过自定义方法来完成逻辑转换 。
@Mapper(componentModel = "spring",uses = {AddressMapper.class})public interface StudentMapper {@Mapping(source = "gender", target = "sex")// @Mapping(source = "address.city", target = "city")@Mapping(source = "address", target = "city",qualifiedByName = "getAddressCity")StudentDTO toDto(Student student);@Named("getAddressCity")default String getChildCircuits(Address address) {if(address == null) {return "";}return address.getCity();}}集合映射使用MapStruct进行集合字段的映射也很简单 。比如每个Student中有多门选修的课程List<Course>,要映射到StudentDTO中的List<CourseDTO>中 。
@Mapper(componentModel = "spring")public interface CourseMapper {CourseDTO toDto(Course port);List<CourseDTO> toCourseDtoList(List<Course> courses);}@Mapper(componentModel = "spring",uses = {CourseMapper.class})public interface StudentMapper {@Mapping(source = "gender", target = "sex")@Mapping(source = "address", target = "city",qualifiedByName = "getAddressCity")CircuitDto toDto(Circuit circuit);}其他特殊情况映射除了常见的对象映射外,有些情况我们可能需要在转换时设置一些固定值,假设StudentDTO中有学历字段degree,但是暂时该数据还未录入,所以这里要设置默认值“未知” 。可以使用@Mapping注解完成 。
@Mapping(target = "degree", constant = "未知")@BeforeMapping和@AfterMapping@BeforeMapping和@AfterMapping是两个很重要的注解,看名字基本就可以猜到,可以用来在转换之前和之后做一些处理 。
比如我们想要在转换之前做一些数据验证,集合初始化等功能,可以使用@BeforeMapping;
想要在转换完成之后进行一些数据结果的修改,比如根据更加StudentDTO中选修课程List<CourseDTO>的数量来给是否有选修课字段haveCourse设置布尔值等 。
@Mapper(componentModel = "spring",uses = {PortMapper.class})public interface StudentMapper {@BeforeMappingdefault void setCourses(Student student) {if(student.getCourses() == null){student.setCourses(new ArrayList<Course>());}}@Mapping(source = "gender", target = "sex")StudentDTO toDto(Student student);@AfterMappingdefault void setHaveCourse(StudentDTO studentDto) {if(studentDto.getCourses()!=null && studentDto.getCourses() >0){studentDto.setHaveCourse(true);}} }总结在本文中介绍了如何使用MapStruct来优雅的实现对象属性映射,减少我们代码中的get,set代码,避免对象属性之间映射的错误 。在以上示例代码中可以看出,MapStruct大量使用了注解,让我们可以轻松完成对象映射 。
如果你想了解更多MapStruct相关信息,可以继续阅读官方的文档 。MapStruct官方文档




推荐阅读