一款PO VO DTO 轉(zhuǎn)換神器,求求你別在到處找工具類(lèi)了!
作者:bettermann
toutiao.com/i6891531055631696395/
老鐵們是不是經(jīng)常為寫(xiě)一些實(shí)體轉(zhuǎn)換的原始代碼感到頭疼,尤其是實(shí)體字段特別多的時(shí)候。介紹一個(gè)開(kāi)源項(xiàng)目 mapstruct ,可以輕松優(yōu)雅的進(jìn)行轉(zhuǎn)換,簡(jiǎn)化你的代碼。當(dāng)然有的人喜歡寫(xiě)get set,或者用BeanUtils 進(jìn)行復(fù)制,代碼只是工具,本文只是提供一種思路。
先貼下官網(wǎng)地址吧:https://mapstruct.org/
廢話不多說(shuō),上代碼:
pom 配置:
????????UTF-8
????????1.8
????????1.8
????????1.4.1.Final
????????1.18.12
????????
????????????org.mapstruct
????????????mapstruct
????????????${org.mapstruct.version}
????????
????????
????????
????????????org.projectlombok
????????????lombok
????????????${org.projectlombok.version}
????????????provided
????????
????????
?????
????????????org.mapstruct
????????????mapstruct-processor
????????????${org.mapstruct.version}
????????????provided
????????
????????
????????????
????????????????org.apache.maven.plugins
????????????????maven-compiler-plugin
????????????????3.8.1
????????????????
????????????????????<source>1.8source>
????????????????????1.8
????????????????????
????????????????????????
????????????????????????????org.projectlombok
????????????????????????????lombok
????????????????????????????${org.projectlombok.version}
????????????????????????
????????????????????????
????????????????????????????org.mapstruct
????????????????????????????mapstruct-processor
????????????????????????????${org.mapstruct.version}
????????????????????????
????????????????????
????????????????
????????????
????????
????
關(guān)于lombok和mapstruct的版本兼容問(wèn)題多說(shuō)幾句,maven插件要使用3.6.0版本以上、lombok使用1.16.16版本以上,另外編譯的lombok mapstruct的插件不要忘了加上。否則會(huì)出現(xiàn)下面的錯(cuò)誤:No property named "aaa" exists in source parameter(s). Did you mean "null"?
這種異常就是lombok編譯異常導(dǎo)致缺少get setter方法造成的。還有就是缺少構(gòu)造函數(shù)也會(huì)拋異常。
@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);
}
實(shí)體類(lèi)是開(kāi)發(fā)過(guò)程少不了的,就算是用工具生成肯定也是要有的,需要手寫(xiě)的部分就是這個(gè)Mapper的接口,編譯完成后會(huì)自動(dòng)生成相應(yīng)的實(shí)現(xiàn)類(lèi)
然后就可以直接用mapper進(jìn)行實(shí)體的轉(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);
????????//這行代碼便是實(shí)際要用的代碼
????????StudentVO?studentVO?=?StudentMapper.INSTANCE.student2StudentVO(student);
????????System.out.println(studentVO);
????}
}
mapper可以進(jìn)行字段映射,改變字段類(lèi)型,指定格式化的方式,包括一些日期的默認(rèn)處理。
可以手動(dòng)指定格式化的方法:
@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();
????}
}
上面只是最簡(jiǎn)單的實(shí)體映射處理,下面介紹一些高級(jí)用法
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.多對(duì)象轉(zhuǎn)換到一個(gè)對(duì)象
@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("語(yǔ)文").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);
}



