當前位置: 妍妍網 > 碼農

別再用 BeanUtils 了,這款 PO VO DTO 轉換神器不香麽?

2024-05-28碼農

老鐵們是不是經常為寫一些實體轉換的原始程式碼感到頭疼,尤其是實體欄位特別多的時候。介紹一個開源計畫 mapstruct ,可以輕松優雅的進行轉換,簡化你的程式碼。當然有的人喜歡寫get set,或者用BeanUtils 進行復制,程式碼只是工具,本文只是提供一種思路。

先貼下官網地址吧:https://mapstruct.org/

廢話不多說,上程式碼:

pom 配置:

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<org.mapstruct.version>1.4.1.Final</org.mapstruct.version>
<org.projectlombok.version>1.18.12</org.projectlombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<!-- lombok dependencies should not end up on classpath -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- idea 2018.1.1 之前的版本需要添加下面的配置,後期的版本就不需要了,可以註釋掉,
我自己用的2019.3 -->

<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>



關於lombok和mapstruct的版本相容問題多說幾句,maven外掛程式要使用3.6.0版本以上、lombok使用1.16.16版本以上,另外編譯的lombok mapstruct的外掛程式不要忘了加上。否則會出現下面的錯誤:No property named "aaa" exists in source parameter(s). Did you mean "null"?

這種異常就是lombok編譯異常導致缺少get setter方法造成的。還有就是缺少建構函式也會拋異常。

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public classStudent{
private String name;
privateint age;
private GenderEnum gender;
private Double height;
private Date birthday;
}
publicenum GenderEnum {
Male("1""男"),
Female("0""女");
private String code;
private String name;
public String getCode(){
returnthis.code;
}
public String getName(){
returnthis.name;
}
GenderEnum(String code, String name) {
this.code = code;
this.name = name;
}
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public classStudentVO{
private String name;
privateint age;
private String gender;
private Double height;
private String birthday;
}
@Mapper
publicinterfaceStudentMapper{
StudentMapper INSTANCE = Mappers.getMapper(StudentMapper. class);
@Mapping(source = "gender.name", target = "gender")
@Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
StudentVO student2StudentVO(Student student);
}







實體類是開發過程少不了的,就算是用工具生成肯定也是要有的,需要手寫的部份就是這個Mapper的介面,編譯完成後會自動生成相應的實作類

然後就可以直接用mapper進行實體的轉換了

public classTest{
publicstaticvoidmain(String[] args){
Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();
System.out.println(student);
//這行程式碼便是實際要用的程式碼
StudentVO studentVO = StudentMapper.INSTANCE.student2StudentVO(student);
System.out.println(studentVO);
}
}



mapper可以進行欄位對映,改變欄位型別,指定格式化的方式,包括一些日期的預設處理。

可以手動指定格式化的方法:

@Mapper
publicinterfaceStudentMapper{
StudentMapper INSTANCE = Mappers.getMapper(StudentMapper. class);
@Mapping(source = "gender", target = "gender")
@Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
StudentVO student2StudentVO(Student student);
default String getGenderName(GenderEnum gender){
return gender.getName();
}
}


上面只是最簡單的實體對映處理,下面介紹一些高級用法


1、List 轉換

內容對映基於上面的mapping配置

@Mapper
publicinterfaceStudentMapper{
StudentMapper INSTANCE = Mappers.getMapper(StudentMapper. class);
@Mapping(source = "gender.name", target = "gender")
@Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
StudentVO student2StudentVO(Student student);

List<StudentVO> students2StudentVOs(List<Student> studentList);
}
publicstaticvoidmain(String[] args){
Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();
List<Student> list = new ArrayList<>();
list.add(student);
List<StudentVO> result = StudentMapper.INSTANCE.students2StudentVOs(list);
System.out.println(result);
}








2、多物件轉換到一個物件

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public classStudent{
private String name;
privateint age;
private GenderEnum gender;
private Double height;
private Date birthday;
}
@Data
@AllArgsConstructor
@Builder
@NoArgsConstructor
public classCourse{
private String courseName;
privateint sortNo;
privatelong id;
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public classStudentVO{
private String name;
privateint age;
private String gender;
private Double height;
private String birthday;
private String course;
}
@Mapper
publicinterfaceStudentMapper{
StudentMapper INSTANCE = Mappers.getMapper(StudentMapper. class);
@Mapping(source = "student.gender.name", target = "gender")
@Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
@Mapping(source = "course.courseName", target = "course")
StudentVO studentAndCourse2StudentVO(Student student, Course course);
}
public classTest{
publicstaticvoidmain(String[] args){
Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();
Course course = Course.builder().id(1L).courseName("語文").build();
StudentVO studentVO = StudentMapper.INSTANCE.studentAndCourse2StudentVO(student, course);
System.out.println(studentVO);
}
}












3、預設值

@Mapper
publicinterfaceStudentMapper{
StudentMapper INSTANCE = Mappers.getMapper(StudentMapper. class);
@Mapping(source = "student.gender.name", target = "gender")
@Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
@Mapping(source = "course.courseName", target = "course")
@Mapping(target = "name", source = "student.name", defaultValue = "張三")
StudentVO studentAndCourse2StudentVO(Student student, Course course);
}


來源:toutiao.com/article/6891531055631696395

>>

END

精品資料,超贊福利,免費領

微信掃碼/長按辨識 添加【技術交流群

群內每天分享精品學習資料

最近開發整理了一個用於速刷面試題的小程式;其中收錄了上千道常見面試題及答案(包含基礎並行JVMMySQLRedisSpringSpringMVCSpringBootSpringCloud訊息佇列等多個型別),歡迎您的使用。

👇👇

👇點選"閱讀原文",獲取更多資料(持續更新中