溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

性能爆棚的實體轉(zhuǎn)換復(fù)制工具MapStruct如何使用

發(fā)布時間:2023-05-11 14:58:42 來源:億速云 閱讀:96 作者:iii 欄目:開發(fā)技術(shù)

這篇“性能爆棚的實體轉(zhuǎn)換復(fù)制工具MapStruct如何使用”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“性能爆棚的實體轉(zhuǎn)換復(fù)制工具MapStruct如何使用”文章吧。

    引言

    Java項目中實體轉(zhuǎn)換無處不在,當(dāng)實體字段較多或者大批量的進行復(fù)制時,通過手工setter/getter顯得太LOW,同時兼?zhèn)涓咝阅芤笄闆r下,MapStruct完全完全能夠勝任。官方解釋,MapStruct是一個代碼生成器,它基于約定優(yōu)于配置的方法,極大地簡化了Java bean類型之間映射的實現(xiàn)。生成的映射代碼使用普通方法調(diào)用,因此快速、類型安全且易于理解。因為MapStruct是在編譯期間生成setter/getter方法,實際運行時就是直接調(diào)用setter/getter,效率會非常高。

    優(yōu)點

    • MapStruct編譯期生成映射代碼,所以可以在編譯時暴露映射錯誤的代碼,讓錯誤提前暴露;

    • 因為使用setter/getter方式,而非反射方式,所以可以更快的執(zhí)行效率;

    • 可以實現(xiàn)深拷貝,自動類型轉(zhuǎn)換,如枚舉轉(zhuǎn)換;

    • 進行自定義的映射,多種映射方式,下邊具體說明;

    性能對比

    對比對象10個對象復(fù)制1次1萬個對象復(fù)制1次100萬個對象復(fù)制1次100萬個對象復(fù)制5次
    MapStruct0ms3ms96ms281ms
    Hutools的BeanUtil23ms102ms1734ms8316ms
    Spring的BeanUtils2ms47ms726ms3676ms
    Apache的BeanUtils20ms156ms10658ms52355ms
    Apache的PropertyUtils5ms68ms6767ms30694ms

    使用

    依賴

    <!-- MapStruct核心,包含了一些必要的注解-->
    <dependencies>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
    </dependencies>
    <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>
                        <!-- MapStruct編譯,注解處理器,根據(jù)注解自動生成Mapper的實現(xiàn) -->
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>

    定義轉(zhuǎn)換接口

    /**
     * 測試接口
     *
     * @author reboot
     */
    @Mapper
    public interface OrderConvertor {
        /**
         * 實例
         */
        OrderConvertor INSTANCE = Mappers.getMapper(OrderConvertor.class);
        /**
         * OrderDo -> OrderModel
         *
         * @param orderDo 訂單實體
         * @return {@link OrderModel}
         */
        OrderModel toModel(OrderDo orderDo);
        /**
         * OrderDo -> OrderModel
         *
         * @param orderDos 訂單實體
         * @return {@link OrderModel}
         */
        List<OrderModel> toModel(List<OrderDo> orderDos);
        /**
         * OrderModel -> OrderDo
         *
         * @param orderModel 訂單模型
         * @return {@link OrderDo}
         */
        OrderDo toDo(OrderModel orderModel);
        /**
         * OrderModel -> OrderDo
         *
         * @param orderModels 訂單模型
         * @return {@link OrderDo}
         */
        List<OrderDo> toDo(List<OrderModel> orderModels);
    }

    編譯結(jié)果

    性能爆棚的實體轉(zhuǎn)換復(fù)制工具MapStruct如何使用

    MapStruct會自動生成對應(yīng)接口的實現(xiàn),并自動完成屬性映射關(guān)系,List會自動進行批量處理。

    調(diào)用

    /**
     * 訂單服務(wù)
     *
     * @author reboot
     */
    @Service
    public class OrderService {
        /**
         * 獲取訂單列表
         *
         * @return {@link List}<{@link OrderModel}>
         */
        public List<OrderModel> getOrderList() {
            // 獲取數(shù)據(jù)庫數(shù)據(jù)DO
            List<OrderDo> result = selectOrderList();
            // 參數(shù)轉(zhuǎn)換
            return OrderConvertor.INSTANCE.toModel(result);
        }
    }

    插件

    性能爆棚的實體轉(zhuǎn)換復(fù)制工具MapStruct如何使用

    上邊的使用方式雖然能夠正常使用,但是在一些屬性配置映射上和提示上,如果使用插件能夠提升使用體驗,IDEA中可以直接安裝Mapstruct Support插件,當(dāng)然Eclipse也有對應(yīng)的插件。

    特性

    • 突出顯示目標(biāo)屬性和源屬性。將目標(biāo)屬性和源屬性轉(zhuǎn)到聲明的setter / getter中;

    • 錯誤和快速修復(fù):


      • 缺少@Mapper或@MapperConfig注解檢查;

      • 快速修復(fù)未映射的目標(biāo)屬性,添加未映射目標(biāo)屬性和忽略未映射目標(biāo)屬性;

    性能爆棚的實體轉(zhuǎn)換復(fù)制工具MapStruct如何使用

    其他用法

    更加詳細的內(nèi)容可以查看官方文檔,發(fā)布文章時最新版本是 MapStruct 1.5.3.Final.html。

    基礎(chǔ)映射

    @Mapper
    public interface CarMapper {
        @Mapping(target = "manufacturer", source = "make")
        @Mapping(target = "seatCount", source = "numberOfSeats")
        CarDto carToCarDto(Car car);
        @Mapping(target = "fullName", source = "name")
        PersonDto personToPersonDto(Person person);
    }

    target表示目標(biāo)屬性名,source表示源屬性名,一般在目標(biāo)屬性和源屬性不同時使用,相同的屬性名會自動進行映射。

    映射器添加自定義方法

    @Mapper
    public interface CarMapper {
        @Mapping(...)
        ...
        CarDto carToCarDto(Car car);
        default PersonDto personToPersonDto(Person person) {
            //hand-written mapping logic
        }
    }

    自定義方法personToPersonDto并實現(xiàn),在生成的實現(xiàn)類中會進行覆蓋使用。

    多個源參數(shù)映射

    @Mapper
    public interface AddressMapper {
        @Mapping(target = "description", source = "person.description")
        @Mapping(target = "houseNumber", source = "address.houseNo")
        DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address);
        @Mapping(target = "description", source = "person.description")
        @Mapping(target = "houseNumber", source = "hn")
        DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Integer hn);
    }

    存在多個源參數(shù),使用參數(shù)名.屬性名的方式進行表示,也可以直接使用基礎(chǔ)類型的屬性名稱。

    嵌套屬性映射到當(dāng)前目標(biāo)

    @Mapper
     public interface CustomerMapper {
         @Mapping( target = "name", source = "record.name" )
         @Mapping( target = ".", source = "record" )
         @Mapping( target = ".", source = "account" )
         Customer customerDtoToCustomer(CustomerDto customerDto);
     }

    當(dāng)源參數(shù)中存在對象屬性,可以手動進行映射,或者直接使用"."的方式將對象中的屬性全部映射到當(dāng)前目標(biāo)對象。

    表達式方式

    @Mapper
    public interface SourceTargetMapper {
        SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class );
        @Mapping(
            target = "timeAndFormat",
            expression = "java( new org.sample.TimeAndFormat( s.getTime(), s.getFormat() ) )"
        )
        Target sourceToTarget(Source s);
    }

    支持使用java代碼塊進行轉(zhuǎn)換,一般可以將靜態(tài)方法處理的字段放到這里。

    更新現(xiàn)有實例

    @Mapper
    public interface CarMapper {
        void updateCarFromDto(CarDto carDto, @MappingTarget Car car);
    }

    @MappingTarget源參數(shù),編譯時會將carDto參數(shù)中的屬性映射到car參數(shù)中。

    Map映射

    @Mapper
    public interface CustomerMapper {
        @Mapping(target = "name", source = "customerName")
        Customer toCustomer(Map<String, String> map);
    }

    直接將map中的key進行映射。

    更多用法

    還有更多其他用法,比如:

    • 支持映射定義的public屬性;

    • 支持映射參數(shù)Builder模式;

    • 使用注入方式引入轉(zhuǎn)換器;

    • 數(shù)據(jù)類型字段轉(zhuǎn)換,如枚舉、日期,支持日期格式化,支持數(shù)字類型格式化,具體可以看 Implicit type conversions;

    • 集合類型自動轉(zhuǎn)換;

    • 轉(zhuǎn)換Stream。

    以上就是關(guān)于“性能爆棚的實體轉(zhuǎn)換復(fù)制工具MapStruct如何使用”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI