具有多个源的MapStruct映射器

时间:2019-10-10 14:04:01

标签: java mapstruct

假设我需要将两个对象映射为一个一个对象映射为一个(重载)。我可以通过以下映射做到这一点:

@Mapper
public interface ThingMapper
{
    @Mappings(
        {
            @Mapping(source = "createdDateTime", target = "thingDate"),
            @Mapping(source = "approver.id", target = "approverId"),
        })
    ThingEventPayload toEventPayload(Thing thing);

    // TODO this is redundant, how to clean up?
    @Mappings(
        {
            // since there are two params, need to specifically map same-named params from source "thing" to target
            @Mapping(source = "thing.id", target = "id"),
            @Mapping(source = "thing.deletedDateTime", target = "deletedDateTime"),
            @Mapping(source = "thing.version", target = "version"),
            @Mapping(source = "thing.autoApproved", target = "autoApproved"),
            @Mapping(source = "thing.resolvedDate", target = "resolvedDate"),
            @Mapping(source = "thing.status", target = "status"),

            // numerous other fields mapping from source "thing" to target with same property name

            // map differently named parameters (duplicate of other mapper, above)
            @Mapping(source = "thing.createdDateTime", target = "thingDate"),
            @Mapping(source = "thing.approver.id", target = "approverId"),

            // mapping second parameter "owner" directory to target "owner" property
            @Mapping(source = "owner", target = "owner"),
        })
    ThingEventPayload toEventPayload(Thing thing, User owner);
}

请注意,默认情况下,第一个映射器将所有字段从源映射到目标(大多数字段名称匹配),但是有两个特定的映射,从源到名称不同的目标字段。

第二个映射器希望将thing all 映射到 root 目标中,就像第一个映射器一样,但是随后还要映射第二个参数{ {1}}到目标的同名owner字段。

是否可以更改第二个映射器“先执行第一个映射器”,然后应用owner的附加映射?

1 个答案:

答案 0 :(得分:1)

在这种情况下,您可以做的是使用自定义方法。

例如

@Mapper
public interface ThingMapper {
    @Mappings(
        {
            @Mapping(source = "createdDateTime", target = "thingDate"),
            @Mapping(source = "approver.id", target = "approverId"),
        })
    ThingEventPayload toEventPayload(Thing thing);

    UserPayload toUserPayload(User user);

    default ThingEventPayload toEventPayload(Thing thing, User owner) {
        ThingEventPayload eventPayload = toEventPayload(thing);
        if (eventPayload != null) {
            eventPayload.setOwner(toUserPayload(owner));
        }
        return eventPayload;
    }
}