MapStruct Mapper с несколькими источниками - PullRequest
2 голосов
/ 10 октября 2019

Предположим, мне нужно отобразить два объекта в один или один объект в один (перегрузка). Я могу сделать это с помощью следующего сопоставления:

@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 в цель root , как это делает первый маппер, но затем дополнительно отображает второйпараметр owner для одноименного поля цели owner.

Есть ли способ изменить второй преобразователь «сначала выполнить первый преобразователь», а затем применить дополнительное отображение @Mapping(source = "owner", target = "owner")?

1 Ответ

1 голос
/ 11 октября 2019

В этом случае вы можете работать с пользовательскими методами.

Например

@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;
    }
}
...