MapStruct到底是什么?
一、簡介
現(xiàn)在的分布式系統(tǒng)中模塊劃分越來越細(xì),不同模塊的實(shí)體、DTO、DO等需要進(jìn)行轉(zhuǎn)換,這么多工程處理起來不是那么簡單。
MapStruct 就是這樣的一個(gè)屬性映射插件,用于為Java Bean生成類型安全且高性能的映射。它基于編譯階段生成get/set代碼,此實(shí)現(xiàn)過程中沒有反射,不會(huì)造成額外的性能損失。只需要定義一個(gè) Mapper 接口,MapStruct 就會(huì)自動(dòng)實(shí)現(xiàn)這個(gè)映射接口,避免了繁瑣的映射實(shí)現(xiàn)。
優(yōu)點(diǎn)
與手工編寫映射代碼相比
- MapStruct通過生成冗長且容易出錯(cuò)的代碼來節(jié)省時(shí)間。
與動(dòng)態(tài)映射框架相比
- 簡單泛型智能轉(zhuǎn)換;
- 效率高:無需手動(dòng) set/get 或 implements Serializable 以達(dá)到深拷貝;
- 性能更高:使用簡單的 Java 方法調(diào)用代替反射;
- 編譯時(shí)類型安全:只能映射相同名稱或帶映射標(biāo)記的屬性;
- 編譯時(shí)產(chǎn)生錯(cuò)誤報(bào)告:如果映射不完整(存在未被映射的目標(biāo)屬性)或映射不正確(找不到合適的映射方法或類型轉(zhuǎn)換)則會(huì)在編譯時(shí)拋出異常。

二、Demo
2.1 導(dǎo)入依賴
使用該插件主要需要導(dǎo)入兩個(gè)包:
::: details Maven | Gradle
Maven
<dependency>
<groupId>org.mapstruct</groupId>
<!-- jdk8以下就使用mapstruct -->
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.0.Final</version>
</dependency>
<!-- 注解處理器 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.0.Final</version>
</dependency>
Gradle
plugins {
...
id "com.diffplug.eclipse.apt" version "3.26.0" // Only for Eclipse
}
dependencies {
...
compile 'org.mapstruct:mapstruct:1.4.2.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
testAnnotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final' // if you are using mapstruct in test code
}
...
2.2 示例代碼
::: details domain、vo、mapper、controller
domain/Person.java
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private Long id;
private String name;
private Integer age;
private Integer sex;
}
vo/PersonVO.java
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PersonVO {
private Long personId;
private String personName;
private Integer age;
}
mapper/PersonMapper.java
@Mapper(componentModel = "spring")
public interface PersonMapper {
/**
* ClassLoader 的方式獲取當(dāng)前 mapper (可以不用)
*/
PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);
/**
* 實(shí)體轉(zhuǎn)VO
* source
* @param person
* @return PersonVO
*/
@Mappings({
@Mapping(source = "id", target = "personId"),
@Mapping(source = "name", target = "personName")
})
PersonVO toPersonVO(Person person);
/**
* VO轉(zhuǎn)實(shí)體
*
* @param person
* @return PersonVO
*/
@Mappings({
@Mapping(source = "personId", target = "id"),
@Mapping(source = "personName", target = "name"),
@Mapping(target = "sex", ignore = true),
})
Person toPerson(PersonVO person);
}
Controller
@RestController
@RequestMapping("/api")
public class TestMapStructController {
@Autowired
PersonMapper personMapper;
@GetMapping("convert")
public List<Object> convertEntity() {
ArrayList<Object> objectList = new ArrayList<>();
Person person = Person.builder()
.id(5L)
.name("zhangsan")
.age(12)
.sex(1)
.build();
objectList.add(person);
PersonVO personVO = personMapper.toPersonVO(person);
Person person1 = personMapper.toPerson(personVO);
objectList.add("person 轉(zhuǎn) personVO" + personVO);
objectList.add("personVO 轉(zhuǎn) person" + person1);
return objectList;
}
}
打包后會(huì)看見 mapstruct 為我們生成了 mapper 的實(shí)現(xiàn)類
三、 注解介紹
@Mapper :MapStruct 注解處理器會(huì)掃描這個(gè)注解
先介紹一下 @Mapper 注解的 componentModel 屬性,該屬性用于自動(dòng)生成的接口實(shí)現(xiàn)類的組件類型,這個(gè)屬性支持四個(gè)值:
1.default : 這是默認(rèn)的情況,mapstruct 不使用任何組件類型, 可以通過Mappers.getMapper(Class)方式獲取自動(dòng)生成的實(shí)例對(duì)象。
2.cdi : 生成的映射器是一個(gè)應(yīng)用程序范圍的 CDI bean,可以通過 @Inject 檢索
3.spring : 生成的實(shí)現(xiàn)類上面會(huì)自動(dòng)添加一個(gè)@Component注解,可以通過Spring的 @Autowired方式進(jìn)行注入
4.jsr330 : 生成的實(shí)現(xiàn)類上會(huì)添加@javax.inject.Named 和@Singleton注解,可以通過 @Inject注解獲取
@Mappings:配置多個(gè)@Mapping
@Mapping 屬性映射,若源對(duì)象屬性與目標(biāo)對(duì)象名字一致,會(huì)自動(dòng)映射對(duì)應(yīng)屬性
1.source :參數(shù)類的屬性
2.target :要轉(zhuǎn)換的類的屬性
3.ignore :配合 target 使用,表示改轉(zhuǎn)換類的的屬性不需要映射
4.expression :配合 target 使用,表示改轉(zhuǎn)換類的的屬性使用指定的表達(dá)式進(jìn)行轉(zhuǎn)換
@Mapping(
target = "someProp",
expression = "java(new TimeAndFormat( s.getTime(), s.getFormat() ))"
)
5.expression :配合 target 使用,表示改轉(zhuǎn)換類的的屬性使用指定的表達(dá)式進(jìn)行轉(zhuǎn)換
@Mapping(
target = "someProp",
expression = "java(new TimeAndFormat( s.getTime(), s.getFormat() ))"
)
其他請(qǐng)參考源文件或官網(wǎng),后續(xù)用到再補(bǔ)充
到此這篇關(guān)于MapStruct到底是什么?的文章就介紹到這了,更多相關(guān)MapStruct的使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中?Jackson?日期的時(shí)區(qū)和日期格式問題解決
因?yàn)樽罱?xiàng)目需要國際化,需要能夠支持多種國際化語言,目前需要支持三種(法語、英語、簡體中文),這篇文章主要介紹了SpringBoot中?Jackson?日期的時(shí)區(qū)和日期格式問題,需要的朋友可以參考下2022-12-12
java使用selenium自動(dòng)化WebDriver等待的示例代碼
顯式等待和隱式等待是WebDriver中兩種常用的等待方式,它們都可以用來等待特定的條件滿足后再繼續(xù)執(zhí)行代碼,本文給大家介紹java使用selenium自動(dòng)化WebDriver等待,感興趣的朋友一起看看吧2023-09-09
一文詳解SpringMVC中的@RequestMapping注解
@RequestMapping是一個(gè)用于映射HTTP請(qǐng)求到處理方法的注解,在Spring框架中使用,它可以用于控制器類和處理方法上,用來指定處理不同URL路徑的請(qǐng)求,并定義請(qǐng)求的方法等,本文小編將給大家詳細(xì)的介紹一下SpringMVC中的@RequestMapping注解,需要的朋友可以參考下2023-08-08
Java判斷字符串是否是整數(shù)或者浮點(diǎn)數(shù)的方法
今天小編就為大家分享一篇Java判斷字符串是否是整數(shù)或者浮點(diǎn)數(shù)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-07-07
SpringBoot整合ElasticSearch的示例代碼
本篇文章主要介紹了SpringBoot整合ElasticSearch的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09

