java - MapStruct:将多个对象的多个源映射到一个目标

标签 java mapstruct object-object-mapping

我想映射以下类

class Schedule {
    ZoneId timezoneId;
    List<AvailabilityRule> rules;
}
class AvailabilityRule {
    long startEpoch;
    long endEpoch;
}

这些类(class)。

class ScheduleDTO {
    String timezone;
    List<AvailabilityRuleDTO> rules;
}
class AvailabilityRuleDTO {
    ZonedDateTime startTime;
    ZonedDateTime endTime;
}

计算startTime需要timezoneIdstartEpoch

Instant instant = Instant.ofEpochMilli(startEpoch);
ZonedDateTime zonedDateTime = instant.atZone(timezoneId);
        

如何使用 mapstruct 实现此目的?

我想要的伪代码

    @Mapping(source = {"startEpoch", "timezoneId"}, target = "startTime", qualifiedByName = "epochToString")
    AvailabilityRuleDTO toAvailabilityRuleDTO(AvailabilityRule
                                                availabilityRule, Schedule schedule);

最佳答案

这可以通过多种方式完成。您在下方看到 2 个选项。它们做同样的事情,只是一个使用 qualifiedByName 而另一个使用 expression。根据您的需要,一个可能比另一个更适合。

使用 mapstruct 找到的自定义方法

qualifiedByName 是必需的,否则 mapstruct 不知道要使用哪种方法。

    @Mapping(source = ".", target = "startTime", qualifiedByName = "startTime")
    @Mapping(source = ".", target = "endTime", qualifiedByName = "endTime")
    AvailabilityRuleDTO toAvailabilityRuleDTO(AvailabilityRule availabilityRule, @Context Schedule schedule);

    @Named("startTime")
    protected ZonedDateTime startTime(AvailabilityRule availabilityRule, @Context Schedule schedule) {
        return convertTime(availabilityRule.startEpoch, schedule.timezoneId);
    }

    @Named("endTime")
    protected ZonedDateTime endTime(AvailabilityRule availabilityRule, @Context Schedule schedule) {
        return convertTime(availabilityRule.endEpoch, schedule.timezoneId);
    }

    private ZonedDateTime convertTime(long epoch, String timezoneId) {
        Instant instant = Instant.ofEpochMilli(epoch);
        ZonedDateTime time = LocalDateTime.from(instant).atZone(timezoneId);
        return time;
    }

使用由表达式配置的自定义方法

@Named 在这里使用是为了防止 mapstruct 不小心将此方法用于其他映射操作。没有它,它很可能仍然有效。

    @Mapping(target = "startTime", expression = "java(convertTime(availabilityRule.startEpoch, schedule.timezoneId))" )
    @Mapping(target = "endTime", expression = "java(convertTime(availabilityRule.endEpoch, schedule.timezoneId))" )
    AvailabilityRuleDTO toAvailabilityRuleDTO(AvailabilityRule
                                                availabilityRule, Schedule schedule);


    @Named("time")
    protected ZonedDateTime convertTime(long epoch, String timezoneId) {
        Instant instant = Instant.ofEpochMilli(epoch);
        ZonedDateTime time = LocalDateTime.from(instant).atZone(timezoneId);
        return time;
    }

包括时间表的完整映射器


@Mapper
public abstract class ScheduleMapper {
    @Mapping(target = "timezone", source = "timezoneId")
    @Mapping(target = "rules", expression = "java(toAvailabilityRuleDTOs(schedule.getRules(), schedule))")
    abstract ScheduleDTO toScheduleDTO(Schedule schedule);

    @Named("rules")
    abstract List<AvailabilityRuleDTO> toAvailabilityRuleDTOs(List<AvailabilityRule> rules, @Context Schedule schedule);

    @Mapping(target = "startTime", expression = "java(convertTime(availabilityRule.startEpoch, schedule.timezoneId))")
    @Mapping(target = "endTime", expression = "java(convertTime(availabilityRule.endEpoch, schedule.timezoneId))")
    abstract AvailabilityRuleDTO toAvailabilityRuleDTO(AvailabilityRule availabilityRule, @Context Schedule schedule);

    @Named("time")
    protected ZonedDateTime convertTime(long epoch, ZoneId timezoneId) {
        Instant instant = Instant.ofEpochMilli(epoch);
        ZonedDateTime time = LocalDateTime.from(instant).atZone(timezoneId);
        return time;
    }

    String map(ZoneId zoneId) {
        return zoneId == null ? null : zoneId.getId();
    }
}

关于java - MapStruct:将多个对象的多个源映射到一个目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70783906/

相关文章:

java - Apache Camel 和 CXF : How do i send HTTP status code from bean

java:查找程序名称,解析整数参数

java - 可以忽略lucene文档boost吗?

java - 如果 MapStruct 中的源为 null,则将父目​​标设置为 null

java - 如何在父对象上使用mapstruct来检测正确的子映射器?

java - 使用 Jackson ObjectMapper 将 Json 的一部分转换为 HashMap

Java ImageIO.read 导致 OSX 挂起

java - 使用 Orika 将实体层次结构映射到 DTO 层次结构

java - 无法用Map、ObjectMapper解析Json