MapStruct到底是什麼?
一、簡介
現在的分佈式系統中模塊劃分越來越細,不同模塊的實體、DTO、DO等需要進行轉換,這麼多工程處理起來不是那麼簡單。
MapStruct 就是這樣的一個屬性映射插件,用於為Java Bean生成類型安全且高性能的映射。它基於編譯階段生成get/set代碼,此實現過程中沒有反射,不會造成額外的性能損失。隻需要定義一個 Mapper 接口,MapStruct 就會自動實現這個映射接口,避免瞭繁瑣的映射實現。
🍭 官網 – 🍤 官方示例
優點
與手工編寫映射代碼相比
- MapStruct通過生成冗長且容易出錯的代碼來節省時間。
與動態映射框架相比
- 簡單泛型智能轉換;
- 效率高:無需手動 set/get 或 implements Serializable 以達到深拷貝;
- 性能更高:使用簡單的 Java 方法調用代替反射;
- 編譯時類型安全:隻能映射相同名稱或帶映射標記的屬性;
- 編譯時產生錯誤報告:如果映射不完整(存在未被映射的目標屬性)或映射不正確(找不到合適的映射方法或類型轉換)則會在編譯時拋出異常。
二、Demo
2.1 導入依賴
使用該插件主要需要導入兩個包:
::: 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 的方式獲取當前 mapper (可以不用) */ PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class); /** * 實體轉VO * source * @param person * @return PersonVO */ @Mappings({ @Mapping(source = "id", target = "personId"), @Mapping(source = "name", target = "personName") }) PersonVO toPersonVO(Person person); /** * VO轉實體 * * @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 轉 personVO" + personVO); objectList.add("personVO 轉 person" + person1); return objectList; } }
打包後會看見 mapstruct 為我們生成瞭 mapper 的實現類
三、 註解介紹
@Mapper :MapStruct 註解處理器會掃描這個註解
先介紹一下 @Mapper
註解的 componentModel
屬性,該屬性用於自動生成的接口實現類的組件類型,這個屬性支持四個值:
1.default : 這是默認的情況,mapstruct 不使用任何組件類型, 可以通過Mappers.getMapper(Class)方式獲取自動生成的實例對象。
2.cdi : 生成的映射器是一個應用程序范圍的 CDI bean,可以通過 @Inject 檢索
3.spring : 生成的實現類上面會自動添加一個@Component註解,可以通過Spring的 @Autowired方式進行註入
4.jsr330 : 生成的實現類上會添加@javax.inject.Named 和@Singleton註解,可以通過 @Inject註解獲取
@Mappings:配置多個@Mapping
@Mapping 屬性映射,若源對象屬性與目標對象名字一致,會自動映射對應屬性
1.source :參數類的屬性
2.target :要轉換的類的屬性
3.ignore :配合 target 使用,表示改轉換類的的屬性不需要映射
4.expression :配合 target 使用,表示改轉換類的的屬性使用指定的表達式進行轉換
@Mapping( target = "someProp", expression = "java(new TimeAndFormat( s.getTime(), s.getFormat() ))" )
5.expression :配合 target 使用,表示改轉換類的的屬性使用指定的表達式進行轉換
@Mapping( target = "someProp", expression = "java(new TimeAndFormat( s.getTime(), s.getFormat() ))" )
其他請參考源文件或官網,後續用到再補充
到此這篇關於MapStruct到底是什麼?的文章就介紹到這瞭,更多相關MapStruct的使用內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 深入理解Java對象復制
- Mapstruct對象插入數據庫某個字段總是為空的bug詳解
- 一小時迅速入門Mybatis之bind與多數據源支持 Java API
- SpringBoot集成mybatis連接oracle的圖文教程
- springboot 整合fluent mybatis的過程,看這篇夠瞭