Java对象属性映射转换器mapStruct,PO转VO或VO转DTO等
在项⽬中,时常有DTO、VO、BO等转换问题时候,我们会使⽤Apache或者Spring的BeanUtils来做copy。他们使⽤的原理都是反射,⽽且是浅拷贝性能不⾼。
场景耗时(调⽤100万次)原理
get/set20ms直接调⽤
MapStruct20ms接⼝映射注⼊(简洁⽅便)
BeanCopiers20ms基于 cglib,修改字节码
BeanUtils12000ms反射
PropertyUtils4000ms反射
MapStruct 性能强悍,时间短,通过⽣成冗长且容易出错的代码来节省时间。在配置⽅法的约定之后,MapStruct使⽤了合理的默认值,但在配置或实现特殊⾏为时将不再适⽤。
“阿⾥巴巴编码规范”也有提尽量避免使⽤BeanUtils⼯具
使⽤get/set代码臃肿不够简洁,BeanUtils 、PropertyUtils 性能不够时间长,⽽BeanCopiers 不过频繁的create太占⽤资源,降低服务器性能,所以推荐使⽤MapStruct 来进⾏对象代码装换。
使⽤MapStruct
官⽅查看官⽹: /
#⽂档讲解⾮常详细
使⽤⽂档:/documentation/stable/reference/html/
引⼊依赖
<mapstruct.version>1.3.1.Final</mapstruct.version>    </properties>
<dependencies>
<!--lombok辅助⼯具-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${mapstruct.version}</version>
</dependency>姓名代码转换器百度
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
</dependencies>
准备⼏个POJO对象⽤来相互装换
@Data
@AllArgsConstructor
@Builder
@NoArgsConstructor
public class Course {
private String courseName; private int sortNo;
private long id;
}
//学⽣实体
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private String name;
private int age;
private GenderEnum gender; private Double height;
private LocalDate birthday;
}
//学⽣响应VO
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StudentVO {
private String name;
private int age;
private String gender;
private Double height;
private String birthday;
private String course;
}
/
/性别枚举测试装换
@Getter
@AllArgsConstructor
public enum GenderEnum {
Male("1","男"),
Female("0","⼥");
private String code;
private String name;
}
定义⼀个装换映射器
import org.mapstruct.MapMapping; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; ity.Course;
ity.Student;
ity.StudentVO;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* POJO映射装换
* @author DuanLinpeng
* @date 2021/01/09 22:12
**/
@Mapper
public interface ConverMapper {
ConverMapper INSTANCE = Mapper(ConverMapper.class);
@Mapping(source ="gender.name", target ="gender")
@Mapping(source ="birthday", target ="birthday", dateFormat ="yyyy-MM-dd")
StudentVO student2StudentVO(Student student);
/**
*  学⽣和科⽬拼接
* @author DuanLinpeng
* @date 2021/01/09 23:33
* @param student
* @param course
* @ity.StudentVO
*/
@Mapping(source ="der.name", target ="gender")
@Mapping(source ="student.birthday", target ="birthday", dateFormat ="yyyy-MM-dd ") @Mapping(source ="urseName", target ="course")
@Mapping(target ="name", source ="student.name", defaultValue ="张三")
StudentVO studentAndCourse2StudentVO(Student student, Course course);
/**
*  集合装换成集合
* @author DuanLinpeng
* @date 2021/01/09 23:25
* @param studentList
* @return java.util.List&ity.StudentVO>
*/
List<StudentVO>students2StudentVOs(List<Student> studentList);
/**
*  Map<Obj> 装换Map<String>
* @author DuanLinpeng
* @date 2021/01/10 13:11
* @param source
* @return java.util.Map<java.lang.String,java.lang.String>
*/
@MapMapping(valueDateFormat ="dd-MM-yyyy")
Map<String, String>LocalDateMapToStringStringMap(Map<Long, LocalDate> source); /**
*  Set<Obj> 装换Set<;指定类型>
* @author DuanLinpeng
* @date 2021/01/10 13:17
* @param integers
* @return java.util.Set<java.lang.String>
*/
Set<String>integerSetToStringSet(Set<Integer> integers);
}
测试启动类
public static void main(String[] args){
//DTO对象装换VO对象
Student student = Student.builder().name("⼩明").age(6).gender(GenderEnum.Male).height(121.1).w()).build();
System.out.println(student);
//这⾏代码便是实际要⽤的代码
StudentVO studentVO = ConverMapper.INSTANCE.student2StudentVO(student);
System.out.println(studentVO);
//List DTO对象装换List VO对象
Student studentlist = Student.builder().name("⼩明").age(6).gender(GenderEnum.Male).height(121.1).w()).build();        List<Student> list =new ArrayList<>();
list.add(studentlist);
List<StudentVO> result = ConverMapper.INSTANCE.students2StudentVOs(list);
System.out.println("List 》》"+result);
//*⼆个对象拼接到⼀起
Student studentSplice = Student.builder().name(null).age(6).gender(GenderEnum.Male).height(121.1).w()).build();        Course courseSplice = Course.builder().id(1L).courseName("语⽂").build();
StudentVO studentSpliceVO = ConverMapper.INSTANCE.studentAndCourse2StudentVO(studentSplice, courseSplice);
System.out.println("Student And Course 》》"+studentSpliceVO);
//Map值Object 类型装换出⾃定Map类型
Map<Long, LocalDate> map =new HashMap<>();
map.put(w());
Map<String, String> mapStr = ConverMapper.INSTANCE.LocalDateMapToStringStringMap(map);
System.out.println("Long And LocalDate 》》"+mapStr);
//Set<Object> 类型装换出⾃定Set类型
Set<Integer> set =new HashSet<>();
set.addAll(Arrays.asList(1,2,3,4,5));
Set<String> stringSet = ConverMapper.INSTANCE.integerSetToStringSet(set);
System.out.println("Set<Integer> To Set<String> 》》"+stringSet);
}
运⾏结果:
Student(name=⼩明, age=6, gender=Male, height=121.1, birthday=2021-01-10)
StudentVO(name=⼩明, age=6, gender=男, height=121.1, birthday=2021-01-10, course=null)
List 》》[StudentVO(name=⼩明, age=6, gender=男, height=121.1, birthday=2021-01-10, course=null)]
Student And Course 》》StudentVO(name=张三, age=6, gender=男, height=121.1, birthday=2021-01-10, course=语⽂)
Long And LocalDate 》》{1=10-01-2021}
Set<Integer> To Set<String>》》[1,2,3,4,5]

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。