這四種對象屬性拷貝方式,你都知道嗎?

這四種對象屬性拷貝方式,你都知道嗎?(推薦第四種)


一、MapStruct

1.1、 簡介:

MapStruct 是一個自動生成 bean 映射類的代碼生成器。MapStruct 還能夠在不同的數(shù)據類型之間進行轉換。

1.2、所需依賴

  • mapstruct-jdk8

包含所需的注釋,例如@Mapping。

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.3.0.Final</version>
</dependency>


  • mapstruct-processor

在編譯,生成映射器實現(xiàn)的注釋處理器。

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.3.0.Final</version>
    <scope>provided</scope>
</dependency>

1.3、如何使用?

您所要做的就是定義一個mapper接口,該接口聲明任何所需的映射方法。在編譯期間,MapStruct將生成此接口的實現(xiàn)。此實現(xiàn)使用普通的Java方法調用來在源對象和目標對象之間進行映射。

  • 創(chuàng)建Mapper

利用@Mapper注解標注該接口/抽象類是被MapStruct自動映射的,只有存在該注解才會將內部的接口方法自動實現(xiàn)。

  • 獲取Mapper

MapStruct為我們提供了多種的獲取Mapper的方式,習慣用默認配置:采用Mappers通過動態(tài)工廠內部反射機制完成Mapper實現(xiàn)類的獲取。

UserConvertUtils INSTANCE = Mappers.getMapper(UserConvertUtils.class);

完整的一個轉換器demo:

@Mapper
public interface UserConvertUtils {

    UserConvertUtils INSTANCE = Mappers.getMapper(UserConvertUtils.class);

    /**
     * 普通的映射
     *
     * @param userDO UserDO數(shù)據持久層類
     * @return 數(shù)據傳輸類
     */
    UserDTO doToDTO(UserDO userDO);

    /**
     * 類型轉換的映射
     *
     * @param userDO UserDO數(shù)據持久層類
     * @return 數(shù)據傳輸類
     */
    @Mappings({
            @Mapping(target = "gmtBroth", source = "gmtBroth", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "balances", source = "balance"),
    })
    UserDTO doToDtoWithConvert(UserDO userDO);
}
  • 測試
/**
 * 一般拷貝
 */
@Test
public void normalCopy() {
    // 模擬查詢出數(shù)據
    UserDO userDO = DataUtil.createData();
    log.info("拷貝前:userDO:{}", userDO);
    UserDTO userDTO = UserConvertUtils.INSTANCE.doToDTO(userDO);
    log.info("拷貝后:userDTO:{}", userDTO);
}
/**
 * 包含類型轉換的拷貝
 */
@Test
public void doToDtoWithConvert() {
    // 模擬查詢出數(shù)據
    UserDO userDO = DataUtil.createData();
    log.info("拷貝前:userDO:{}", userDO);
    UserDTO userDTO = UserConvertUtils.INSTANCE.doToDtoWithConvert(userDO);
    log.info("拷貝后:userDTO:{}", userDTO);
}
  • 打印映射結果
一般拷貝:
...拷貝前:userDO:UserDO(id=1, userName=Van, gmtBroth=2020-04-21T21:38:39.376, balance=100)
...拷貝后:userDTO:UserDTO(id=1, userName=Van, gmtBroth=2020-04-21T21:38:39.376, balances=null)
包含類型轉換的拷貝:
...拷貝前:userDO:UserDO(id=1, userName=Van, gmtBroth=2020-04-21T21:05:19.282, balance=100)
...拷貝后:userDTO:UserDTO(id=1, userName=Van, gmtBroth=2020-04-21 21:05:19, balances=100)

通過打印結果可以發(fā)現(xiàn):相較于前者,包含類型轉換的拷貝可以自定義轉換屬性和時間格式等。


1.4、MapStruct 注解的關鍵詞

  1. @Mapper:只有在接口加上這個注解, MapStruct 才會去實現(xiàn)該接口;
  2. @Mappings:配置多個@Mapping;
  3. @Mapping:屬性映射,若源對象屬性與目標對象名字一致,會自動映射對應屬性:
  • source:源屬性;
  • target:目標屬性;
  • dateFormat:字符串與日期之間相互轉換;
  • ignore:忽略這個,某個屬性不想映射,可以加個 ignore=true;


1.5、多對一

與手工編寫映射代碼相比,MapStruct通過生成繁瑣且易于編寫的代碼來節(jié)省時間。遵循約定優(yōu)于配置方法,MapStruct使用合理的默認值,但在配置或實現(xiàn)特殊行為時會采取措施。
與動態(tài)映射框架相比,MapStruct具有以下優(yōu)勢:

  1. 通過使用普通方法調用而不是反射來快速執(zhí)行
  2. 編譯時類型安全:只能映射相互映射的對象和屬性,不會將訂單實體意外映射到客戶DTO等。
  3. 在構建時清除錯誤報告,如果映射不完整(并非所有目標屬性都已映射)映射不正確(找不到合適的映射方法或類型轉換)
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容