一款 PO VO DTO 轉(zhuǎn)換神器
老鐵們是不是經(jīng)常為寫一些實體轉(zhuǎn)換的原始代碼感到頭疼,尤其是實體字段特別多的時候。介紹一個開源項目 mapstruct ,可以輕松優(yōu)雅的進(jìn)行轉(zhuǎn)換,簡化你的代碼。
當(dāng)然有的人喜歡寫get set,或者用BeanUtils 進(jìn)行復(fù)制,代碼只是工具,本文只是提供一種思路。
先貼下官網(wǎng)地址吧:https://mapstruct.org/
廢話不多說,上代碼:
pom 配置:
<properties>
????????<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
????????<maven.compiler.source>1.8maven.compiler.source>
????????<maven.compiler.target>1.8maven.compiler.target>
????????<org.mapstruct.version>1.4.1.Finalorg.mapstruct.version>
????????<org.projectlombok.version>1.18.12org.projectlombok.version>
properties>
<dependencies>
????????<dependency>
????????????<groupId>org.mapstructgroupId>
????????????<artifactId>mapstructartifactId>
????????????<version>${org.mapstruct.version}version>
????????dependency>
????????
????????<dependency>
????????????<groupId>org.projectlombokgroupId>
????????????<artifactId>lombokartifactId>
????????????<version>${org.projectlombok.version}version>
????????????<scope>providedscope>
????????dependency>
????????
?????<dependency>
????????????<groupId>org.mapstructgroupId>
????????????<artifactId>mapstruct-processorartifactId>
????????????<version>${org.mapstruct.version}version>
????????????<scope>providedscope>
????????dependency>
dependencies>
<build>
????????<plugins>
????????????<plugin>
????????????????<groupId>org.apache.maven.pluginsgroupId>
????????????????<artifactId>maven-compiler-pluginartifactId>
????????????????<version>3.8.1version>
????????????????<configuration>
????????????????????<source>1.8source>
????????????????????<target>1.8target>
????????????????????<annotationProcessorPaths>
????????????????????????<path>
????????????????????????????<groupId>org.projectlombokgroupId>
????????????????????????????<artifactId>lombokartifactId>
????????????????????????????<version>${org.projectlombok.version}version>
????????????????????????path>
????????????????????????<path>
????????????????????????????<groupId>org.mapstructgroupId>
????????????????????????????<artifactId>mapstruct-processorartifactId>
????????????????????????????<version>${org.mapstruct.version}version>
????????????????????????path>
????????????????????annotationProcessorPaths>
????????????????configuration>
????????????plugin>
????????plugins>
????build>關(guān)于lombok和mapstruct的版本兼容問題多說幾句,maven插件要使用3.6.0版本以上、lombok使用1.16.16版本以上,另外編譯的lombok mapstruct的插件不要忘了加上。否則會出現(xiàn)下面的錯誤:
No property named "aaa" exists in source parameter(s). Did you mean "null"?
這種異常就是lombok編譯異常導(dǎo)致缺少get setter方法造成的。還有就是缺少構(gòu)造函數(shù)也會拋異常。
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public?class?Student {
????private?String?name;
????private?int age;
????private?GenderEnum gender;
????private?Double height;
????private?Date?birthday;
}
public?enum?GenderEnum {
????Male("1", "男"),
????Female("0", "女");
????private?String?code;
????private?String?name;
????public?String?getCode() {
????????return?this.code;
????}
????public?String?getName() {
????????return?this.name;
????}
????GenderEnum(String?code, String?name) {
????????this.code = code;
????????this.name = name;
????}
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public?class?StudentVO {
????private?String?name;
????private?int age;
????private?String?gender;
????private?Double height;
????private?String?birthday;
}
@Mapper
public?interface?StudentMapper {
????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);
}實體類是開發(fā)過程少不了的,就算是用工具生成肯定也是要有的,需要手寫的部分就是這個Mapper的接口,編譯完成后會自動生成相應(yīng)的實現(xiàn)類

然后就可以直接用mapper進(jìn)行實體的轉(zhuǎn)換了
public?class?Test?{
????public?static?void?main(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可以進(jìn)行字段映射,改變字段類型,指定格式化的方式,包括一些日期的默認(rèn)處理。
可以手動指定格式化的方法:
@Mapper
public?interface?StudentMapper?{
????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 轉(zhuǎn)換
屬性映射基于上面的mapping配置
@Mapper
public?interface?StudentMapper?{
????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 students2StudentVOs(List studentList);
}
public?static?void main(String[] args) {
????Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new?Date()).build();
????List list?= new?ArrayList<>();
????list.add(student);
????List result = StudentMapper.INSTANCE.students2StudentVOs(list);
????System.out.println(result);
} 
2.多對象轉(zhuǎn)換到一個對象
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public?class?Student?{
????private?String name;
????private?int?age;
????private?GenderEnum gender;
????private?Double height;
????private?Date birthday;
}
@Data
@AllArgsConstructor
@Builder
@NoArgsConstructor
public?class?Course?{
????private?String courseName;
????private?int?sortNo;
????private?long?id;
}
@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;
}
@Mapper
public?interface?StudentMapper?{
????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?class?Test?{
????public?static?void?main(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.默認(rèn)值
@Mapper
public?interface?StudentMapper?{
????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/i6891531055631696395
(完)
?關(guān)注公眾號:Java后端編程,回復(fù)下面關(guān)鍵字?
要Java學(xué)習(xí)完整路線,回復(fù)??路線?
缺Java入門視頻,回復(fù):?視頻?
要Java面試經(jīng)驗,回復(fù)??面試?
缺Java項目,回復(fù):?項目?
進(jìn)Java粉絲群:?加群?
PS:如果覺得我的分享不錯,歡迎大家隨手點贊、在看。
(完) 加我"微信"?獲取一份 最新Java面試題資料 請備注:666,不然不通過~
最近好文
最近面試BAT,整理一份面試資料《Java面試BAT通關(guān)手冊》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫、數(shù)據(jù)結(jié)構(gòu)等等。 獲取方式:關(guān)注公眾號并回復(fù)?java?領(lǐng)取,更多內(nèi)容陸續(xù)奉上。 明天見(??ω??)??
