天天看點

【程式設計提效】MapStruct對象映射架構(Java Mapping Frameworks)背景/場景常見的工具類性能對比MapStruct使用安裝 MapStruct 插件MapStruct技術總結參考

背景/場景

我們在程式設計過程中,經常存在實體類的轉換。如資料庫層對象pojo類 與 底層對外傳輸的對象 xxResponse類。一般常用的方式是每個值去get/set。幸運的是,我們有很多架構可以解決這種問題。

常見的工具類

  • Spring BeanUtils
  • Apache BeanUtils
  • Dozer
  • Orika
  • MapStruct
  • ModelMapper
  • JMapper

    那我們如何選擇這些工具呢

性能對比

不啰嗦,直接上圖

【程式設計提效】MapStruct對象映射架構(Java Mapping Frameworks)背景/場景常見的工具類性能對比MapStruct使用安裝 MapStruct 插件MapStruct技術總結參考

總之,就是 MapStruct性能在各種綜合情況下最優

MapStruct使用

maven依賴引入

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.3.1.Final</version>
</dependency>
<!-- lombok插件 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
    <scope>provided</scope>
</dependency>
           

打包

<build>
     <plugins>
         <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-compiler-plugin</artifactId>
             <version>3.8.1</version>
             <configuration>
                 <source>1.8</source>
                 <target>1.8</target>
                 <annotationProcessorPaths>
                     <path>
                         <groupId>org.mapstruct</groupId>
                         <artifactId>mapstruct-processor</artifactId>
                         <version>1.3.1.Final</version>
                     </path>
                     <path>
                         <groupId>org.projectlombok</groupId>
                         <artifactId>lombok</artifactId>
                         <version>1.18.12</version>
                     </path>
                 </annotationProcessorPaths>
             </configuration>
         </plugin>
     </plugins>
 </build>
           

示例代碼(拷貝到IDE可直接運作)

public class Test {
    public static void main(String[] args) {
        UserDo userDo = new UserDo("zhangsan", 20, "酒仙橋");
        UserResp userResp = SourceMapper.MAPPER.convert(userDo);
        System.out.println( JSON.toJSONString(userResp));
    }
}

/**
 * 原始對象
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
class UserDo {
    private String name;
    private int age;
    private String address;
}


/**
 * 傳回給前端的對象
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
class UserResp {
    private String name;
    //這裡故意少掉 age屬性,看缺失字段是否會成功

	//這裡故意寫成 addr屬性,測試名稱不同能否轉換
    private String addr;
}

/**
 * 轉換器
 */
@Mapper
interface SourceMapper{
    SourceMapper MAPPER = Mappers.getMapper( SourceMapper.class );
	/**
     * 對象轉換時參數不對應使用 @Mapping注解 顯示指定值的對應關系
     * 如果存在多個可使用 @Mappings注解,裡面是個集合
     * 如 @Mappings(value = {
     *             @Mapping(source = "aa", target = "bb" ),
     *             @Mapping(source = "cc", target = "dd" )})
     * @param userDo
     * @return
     */
    @Mapping( source = "address", target = "addr" )
    UserResp convert( UserDo userDo );
}
           

代碼編譯後

在 target/generated-sources/annotations 目錄會自動生成 SourceMapper的實作類

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-05-23T13:08:56+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_60 (Oracle Corporation)"
)
class SourceMapperImpl implements SourceMapper {
    @Override
    public UserResp convert(UserDo userDo) {
        if ( userDo == null ) {
            return null;
        }
        UserResp userResp = new UserResp();
        userResp.setAddr( userDo.getAddress() );
        userResp.setName( userDo.getName() );
        return userResp;
    }
}
           

安裝 MapStruct 插件

在 IDEA 中依次打開 File - > Settings - > Plugins

然後在 Markeyplace 搜尋框中輸入 mapstruct,點選 install,然後重新開機 IDE 即可,不再啰嗦啦

MapStruct技術總結

技術要領

  • 需要寫個接口做轉換器
  • 接口類上需要聲明 @Mapper 注解
  • 接口中需聲明 SourceMapper MAPPER = Mappers.getMapper( SourceMapper.class );
  • 接口中寫要轉換的接口:
    • 參數為原始對象,
    • 傳回為 要傳回的對象
    • 接口上聲明要轉換的具體參數

架構優點

  • 相對反射來說
    • 架構使用注解生成代碼,運作時比較高效。
    • 反射debug困難,這裡debug直接到生成的代碼中了
  • 編寫層面來說
    • 寫法快捷高效
    • 手寫 set 方法屬性太多還容易漏,這裡不會
    • 名字不對應恰好又不想傳回的屬性自動過濾,簡直不要太友善了

參考

  • 芋道源碼mapStruct文章:http://www.iocoder.cn/Spring-Boot/MapStruct/
  • 架構/工具性能對比:https://www.baeldung.com/java-performance-mapping-frameworks
  • mapstruct官網:https://mapstruct.org/
  • 官方文檔:https://mapstruct.org/documentation/stable/reference/html/#shared-configurations
  • 官方git代碼示例:https://github.com/mapstruct/mapstruct-examples