成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MapStruct教程-四種條件映射實(shí)現(xiàn)

開發(fā) 前端
我們的例子中傳入的是屬性,還可以直接傳入源對(duì)象。還有其他的比如@TargetPropertyName、@SourcePropertyName、@Context等高級(jí)用法。

MapStruct是一個(gè)效率工具,可以在處理Java Bean映射時(shí),幫助我們盡量減少樣板代碼,只需要定義接口,它會(huì)自動(dòng)生成映射邏輯。本文中,我們一起看下如何使用MapStruct進(jìn)行條件映射。

一、準(zhǔn)備

在對(duì)象之間映射數(shù)據(jù)時(shí),我們經(jīng)常需要根據(jù)某些條件映射屬性,MapStruct提供了一些配置選項(xiàng)來(lái)實(shí)現(xiàn)這一點(diǎn)。

我們定義一個(gè)目標(biāo)對(duì)象License,該對(duì)象需要根據(jù)一些條件映射屬性:

public class License {
    private UUID id;
    private OffsetDateTime startDate;
    private OffsetDateTime endDate;
    private boolean active;
    private boolean renewalRequired;
    private LicenseType licenseType;

    public enum LicenseType {
        INDIVIDUAL, FAMILY
    }
}

在定義一個(gè)源對(duì)象LicenseDto,包含可選的startDate、endDate和licenseType:

public class LicenseDto {
    private UUID id;
    private LocalDateTime startDate;
    private LocalDateTime endDate;
    private String licenseType;
}

以下是從LicenseDto到License的映射規(guī)則:

  • id:如果LicenseDto有id,則賦值;
  • startDate:如果LicenseDto沒(méi)有startDate,設(shè)置為當(dāng)前日期;
  • endDate:如果LicenseDto沒(méi)有endDate,設(shè)置為從當(dāng)前日期起一年后;
  • active:如果endDate在未來(lái),我們將其設(shè)置為true;
  • renewalRequired:如果endDate在接下來(lái)的兩周內(nèi),我們將其設(shè)置為true;
  • licenseType:如果輸入的licenseType不為空且值是預(yù)期值INDIVIDUAL或FAMILY之一,則轉(zhuǎn)為枚舉并賦值。

上述規(guī)則其實(shí)很簡(jiǎn)單,如果是手寫代碼也能實(shí)現(xiàn),不過(guò)既然有工具,還是要高效使用工具。

二、使用MapStruct進(jìn)行條件映射

我們一起看下,如何通過(guò)MapStruct實(shí)現(xiàn)上述邏輯。

(一)使用表達(dá)式

MapStruct提供了在映射表達(dá)式中,使用Java代碼的功能。讓我們利用此功能映射startDate:

@Mapper
public interface LicenseMapper {
    @Mapping(target = "startDate", expression = "java(mapStartDate(licenseDto))")
    License toLicense(LicenseDto licenseDto);

    default OffsetDateTime mapStartDate(LicenseDto licenseDto) {
        return licenseDto.getStartDate() != null
               ? licenseDto.getStartDate().atOffset(ZoneOffset.UTC) : OffsetDateTime.now();
    }
}

我們可以在@Mapping定義expression指定該字段賦值的Java代碼。我們看下MapStruct生成的代碼:

@Override
public License toLicense(LicenseDto licenseDto) {
    if ( licenseDto == null ) {
        return null;
    }

    License license = new License();
    license.setStartDate( mapStartDate(licenseDto) );
    // 其余生成的映射...
    return license;
}

我們也可以這樣寫:

@Mapping(target = "startDate", expression = "java(licenseDto.getStartDate() != null ? licenseDto.getStartDate().atOffset(java.time.ZoneOffset.UTC) : java.time.OffsetDateTime.now())")
License toLicense(LicenseDto licenseDto);

直接把三元運(yùn)算符的邏輯放到expression表達(dá)式中,也能正常運(yùn)行。

(二)使用條件表達(dá)式

MapStruct還提供了條件表達(dá)式,允許根據(jù)字符串中的條件表達(dá)式映射屬性。我們一起利用此功能映射License中的renewalRequired字段:

@Mapping(target = "renewalRequired", conditionExpression = "java(isEndDateInTwoWeeks(licenseDto))", source = ".")
License toLicense(LicenseDto licenseDto);

default boolean isEndDateInTwoWeeks(LicenseDto licenseDto) {
    return licenseDto.getEndDate() != null
            && Duration.between(licenseDto.getEndDate(), LocalDateTime.now()).toDays() <= 14;
}

我們可以在java()方法中傳遞任何有效的Java布爾表達(dá)式。

在編譯時(shí),MapStruct可以生成代碼來(lái)設(shè)置renewalRequired:

@Override
public License toLicense(LicenseDto licenseDto) {
    if ( licenseDto == null ) {
        return null;
    }

    License license = new License();

    if ( isEndDateInTwoWeeks(licenseDto) ) {
        license.setRenewalRequired( isEndDateInTwoWeeks( licenseDto ) );
    }
    // 其余生成的映射...
    return license;
}

可以看到,生成的代碼在if塊中包含條件。當(dāng)條件匹配時(shí),將使用源中的相應(yīng)值填充所需的屬性。

(三)使用映射前/后操作

在某些情況下,如果我們希望在映射之前或之后通過(guò)自定義修改對(duì)象,可以使用MapStruct的@BeforeMapping和@AfterMapping注解。

我們可以使用此功能有條件地映射endDate:

@Mapping(target = "endDate", ignore = true)
License toLicense(LicenseDto licenseDto);

我們可以定義AfterMapping注解來(lái)有條件地映射endDate。通過(guò)這種方式,我們可以根據(jù)特定條件控制映射:

@AfterMapping
default void afterMapping(LicenseDto licenseDto, @MappingTarget License license) {
    OffsetDateTime endDate = licenseDto.getEndDate() != null ? licenseDto.getEndDate().atOffset(ZoneOffset.UTC)
                                                             : OffsetDateTime.now().plusYears(1);
    license.setEndDate(endDate);
}

我們需要將輸入的LicenseDto和目標(biāo)License對(duì)象都作為參數(shù)傳遞給afterMapping方法。確保了MapStruct生成在返回License對(duì)象之前作為映射的最后一步調(diào)用此方法。

MapStruct生成的代碼是:

@Override
public License toLicense(LicenseDto licenseDto) {
    if ( licenseDto == null ) {
        return null;
    }

    License license = new License();

    // 其余生成的映射...

    afterMapping( licenseDto, license );

    return license;
}

同樣的,我們也可以使用BeforeMapping注解來(lái)達(dá)到相同的結(jié)果。

(四)使用@Condition

在映射時(shí),我們可以使用@Condition為屬性添加自定義存在性檢查。

默認(rèn)情況下,MapStruct會(huì)對(duì)每個(gè)屬性執(zhí)行存在性檢查,但如果有@Condition注解的方法,則優(yōu)先使用該方法。

讓我們使用此功能映射licenseType。

源對(duì)象LicenseDto的licenseType是String類型,在映射期間,如果它不為null且解析為預(yù)期的枚舉INDIVIDUAL或FAMILY之一,我們需要將其映射到目標(biāo)。我們先定義條件函數(shù):

@Condition
default boolean mapsToExpectedLicenseType(String licenseType) {
    try {
        if (licenseType == null) {
            return false;
        }
        License.LicenseType.valueOf(licenseType);
        return true;
    } catch (IllegalArgumentException e) {
        return false;
    }
}

方法mapsToExpectedLicenseType的參數(shù)類型是String,與LicenseDto中的licenseType匹配,MapStruct在映射licenseType時(shí)生成使用此方法mapsToExpectedLicenseType()的代碼:

@Override
public License toLicense(LicenseDto licenseDto) {
    if ( licenseDto == null ) {
        return null;
    }

    License license = new License();
    if ( mapsToExpectedLicenseType( licenseDto.getLicenseType() ) ) {
        license.setLicenseType( Enum.valueOf( License.LicenseType.class, licenseDto.getLicenseType() ) );
    }
    // 其余生成的映射...
    return license;
}

我們的例子中傳入的是屬性,還可以直接傳入源對(duì)象。還有其他的比如@TargetPropertyName、@SourcePropertyName、@Context等高級(jí)用法。

在筆者實(shí)踐時(shí),這些配置雖然能夠解決問(wèn)題,但是有過(guò)渡依賴MapStruct或者炫技的嫌疑。我們要的是少寫無(wú)營(yíng)養(yǎng)代碼,不是引入太多不可控因素,給自己埋雷。

責(zé)任編輯:武曉燕 來(lái)源: 看山的小屋
相關(guān)推薦

2021-12-22 09:34:01

Golagn配置方式

2011-03-16 09:05:53

NATiptables

2025-01-13 00:00:00

MapStruct枚舉映射

2010-08-05 09:33:08

Flex頁(yè)面跳轉(zhuǎn)

2025-01-10 00:00:00

MapStructArticlePerson

2015-04-02 16:54:52

災(zāi)難恢復(fù)VDI災(zāi)難恢復(fù)

2015-04-13 11:39:26

VDI災(zāi)難恢復(fù)

2021-10-24 08:37:18

網(wǎng)絡(luò)監(jiān)控網(wǎng)絡(luò)架構(gòu)網(wǎng)絡(luò)

2022-01-12 11:02:01

云計(jì)算安全技術(shù)

2023-07-11 10:24:00

分布式限流算法

2025-01-13 00:00:00

MapStruct繼承關(guān)系Java

2015-03-19 15:13:20

PHP基本排序算法代碼實(shí)現(xiàn)

2010-07-16 13:50:53

Perl哈希表

2019-10-24 07:42:28

Java引用GC

2017-07-06 15:40:19

DevOps核心能力

2022-08-01 07:56:23

React Hook開發(fā)組件

2012-09-11 09:55:26

編程HTML5編程能力

2014-12-25 09:41:15

Android加載方式

2013-07-29 10:10:40

TCP協(xié)議TCP定時(shí)器TCP

2009-12-09 11:03:45

安裝Linux
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产成人啪免费观看软件 | 久久亚洲一区二区三区四区 | 国产精品久久久久久久久久免费 | 国产精品成人一区二区三区夜夜夜 | 亚洲热在线视频 | 91视频播放 | 欧美日韩高清 | 国产在线网址 | 金莲网 | 久久久九九 | 国产精品精品 | 天天草天天干天天 | www.99精品 | 国产在线视频在线观看 | 国产午夜视频 | 日日骚视频 | 亚洲日本国产 | 亚洲在线免费 | 日韩综合 | 这里有精品| 一区在线免费视频 | 欧美不卡一区二区三区 | 国产农村妇女精品一区 | 国产视频不卡一区 | www.xxxx欧美 | 色黄爽 | 日韩精品在线免费观看视频 | 免费国产精品久久久久久 | 国产一区二区三区在线视频 | 在线观看第一页 | 麻豆久久久久 | 日韩影院在线观看 | 欧美一卡二卡在线观看 | 国产精品毛片av | 91精品国产综合久久小仙女图片 | 91啪亚洲精品 | 射欧美 | 亚洲精品久久 | 亚洲精品一区二区三区免 | 成人av免费| 精品国产乱码久久久久久丨区2区 |