介紹
在工作中,我們經常要進行各種對象之間的轉換。
PO:persistent object 持久對象,對應數據庫中的一條記錄
VO:view object 表現層對象,最終返回給前端的對象
DTO:data transfer object數據傳輸對象,如dubbo服務之間傳輸的對象
如果這些對象的屬性名相同還好,可以用如下工具類賦值
Spring BeanUtils
Cglib BeanCopier
避免使用Apache BeanUtils,性能較差
如果屬性名不同呢?如果是將多個PO對象合併成一個VO對象呢?好在有MapStruct神器,可以幫助我們快速轉換
在pom文件中加入如下依賴即可
<code><
dependency
><
groupId
>org.mapstructgroupId
><
artifactId
>mapstruct-jdk8artifactId
><
version
>1.2.0.CR1version
>dependency
><
dependency
><
groupId
>org.mapstructgroupId
><
artifactId
>mapstruct-processorartifactId
><
version
>1.2.0.CR1version
><
scope
>providedscope
>dependency
>/<code>
對象互轉
<code>@Data
@Builder
public class StudentPO {private
Integer
id
;private
String
name
;private
Integer
age
;private
String
className
; }/<code>
<code>public
class
StudentVO {private
Integer id;private
String
studentName;private
Integer studentAge;private
String
schoolName; }/<code>
<code>public
interface
StudentMapper
{ StudentMapper INSTANCE = Mappers.getMapper(StudentMapper.
class
); ({ (source ="name"
, target ="studentName"
), (source ="age"
, target ="studentAge"
) })StudentVO
po2Vo
(StudentPO studentPO)
; }/<code>
- 新建一個Mapper接口,上面加上@Mapper註解
- 新建一個成員變量INSTANCE
- 用@Mapping註解指定映射關係,名字相同的就不用再指定了,會自動映射
測試效果如下,名字不同且沒有指定映射關係的會被設置為null
<code>@Test
public
void
studentPo2Vo
() { StudentPO studentPO = StudentPO.builder().id(10
).name("test"
) .age(24
).className("教室名"
).build(); StudentVO studentVO = StudentMapper.INSTANCE.po2Vo(studentPO); System.out
.println(studentVO); }/<code>
List互轉
<code>public
interface
StudentMapper
{ StudentMapper INSTANCE = Mappers.getMapper(StudentMapper.
class
); ({ (source ="name"
, target ="studentName"
), (source ="age"
, target ="studentAge"
) })StudentVO
po2Vo
(StudentPO studentPO)
;List
poList2VoList
(List studentPO)
; }/<code>
List類型互轉的映射規則會用單個對象的映射規則,看測試效果
<code>@Test
public
void
poList2VoList
() { List studentPOList =new
ArrayList<>();for
(int
i =1
; i <=2
; i++) { StudentPO studentPO = StudentPO.builder().id(i).name(String.valueOf(i)).age(i).build(); studentPOList.add
(studentPO); } List studentVOList = StudentMapper.INSTANCE.poList2VoList(studentPOList); System.out
.println(studentVOList); }/<code>
多個對象映射一個對象
我們用SchoolPO和StudentPO來映射SchoolStudentVO
<code>@Data
@Builder
public class SchoolPO {private
String
name
;private
String
location
; }/<code>
<code>@Data
@Builder
public class StudentPO {private
Integer
id
;private
String
name
;private
Integer
age
;private
String
className
; }/<code>
<code>public
class
SchoolStudentVO {private
String
schoolName;private
String
studentName; }/<code>
<code>@Mapper
public interface StudentMapper {@Mappings
({@Mapping
(source ="schoolPO.name"
, target ="schoolName"
),@Mapping
(source ="studentPO.name"
, target ="studentName"
) }) SchoolStudentVO mergeVo(SchoolPO schoolPO, StudentPO studentPO); }/<code>
測試例子如下
<code>@Test
public
void
mergeVo
() { SchoolPO schoolPO = SchoolPO.builder().name("學校名字"
).build(); StudentPO studentPO = StudentPO.builder().name("學生名字"
).build(); SchoolStudentVO schoolStudentVO = StudentMapper.INSTANCE.mergeVo(schoolPO, studentPO); System.out
.println(schoolStudentVO); }/<code>
當然還有其他的騷操作,這裡就簡單介紹一個比較實用的技巧,有興趣的可以看官方的example
https://github.com/mapstruct/mapstruct-examples
專欄
Java面試通關100問
19.9幣
285人已購
關鍵字: 對象 name StudentMapper