Автоматическое сопоставление всех полей, кроме одного, которое должно быть передано через какую-то другую функцию - PullRequest
0 голосов
/ 08 января 2019

С помощью Mapstruct, как я могу создать картограф, который будет автоматически отображать все поля, кроме одного (или двух, трех и т. Д.), Которые должны быть пропущены через некоторую пользовательскую логику отображения?

Mapper

@Mapper
public interface MyEntityMapper
{
    MyEntityMapper INSTANCE = Mappers.getMapper(MyEntityMapper.class);

    @Mappings(
        {
            @Mapping(source = "createdByPerson.id", target = "createdByPersonId"),
        })
    MyEventPayload toEventPayload(MyEntity entity);
}

Если у меня есть поле someString, для которого нужно сначала выполнить какую-то настраиваемую запись сопоставления, как бы я это сделал? Я вижу эту опцию argument для @Mapping, но кажется немного сумасшедшим писать код Java в строке внутри аннотации!

Я надеялся сделать что-то вроде:

@MappingFor(MyEntity.class, "someString")
default String mapSomeString(String value) {
    return value + " custom mapping ";
}

Обновление

Я нашел @AfterMapping и использовал его, например .:

@AfterMapping
public void mapSomeString(MyEntity entity, MyEventPayload payload) {
    // do fancy stuff here
}

Но мне все еще любопытно, можете ли вы предоставить функции для каждого поля после сопоставления / пользовательского сопоставления.

Ответы [ 3 ]

0 голосов
/ 10 января 2019

Я использовал @AfterMapping, например ::1001*

@AfterMapping
public void mapSomeString(MyEntity entity, MyEventPayload payload) {
    // do fancy stuff here
}
0 голосов
/ 10 января 2019

Если вы хотите отобразить отдельное поле определенным образом, вы можете использовать Выбор методов отображения на основе квалификаторов .

Это выглядит как

@Mapper
public interface MyEntityMapper {

    @Mapping(target = "someString", qualifiedByName = "myFancyMapping")
    MyEventPayload toEventPayload(MyEntity entity);

    @Named("myFancyMapping") // org.mapstruct.Named
    default String mapSomeString(String value) {
        return value + " custom mapping ";
    }
}

Вы также можете использовать Mapping#qualifiedBy и создать собственную Qualifier (org.mapstruct.Qualifier) аннотацию.

Это выглядит так:

@Qualifier // org.mapstruct.Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface MyFancyMapping {
}

@Mapper
public interface MyEntityMapper {

    @Mapping(target = "someString", qualifiedBy = MyFancyMapping.class)
    MyEventPayload toEventPayload(MyEntity entity);

    @MyFancyMapping
    default String mapSomeString(String value) {
        return value + " custom mapping ";
    }
}

Альтернативный

Альтернативой может быть создание пользовательского сопоставления в @AfterMapping или с выражением (я не рекомендую использовать выражения, поскольку оно подвержено ошибкам).

0 голосов
/ 10 января 2019

Вы смотрели на Expressions MapStruct?

Вот пример из Документов:

@Mapping(target = "timeAndFormat",
     expression = "java( new org.sample.TimeAndFormat( s.getTime(), s.getFormat() ) )")

Вместо new org.sample.TimeAndFormat... вы можете использовать ваш конструктор класса или метод.

...