2016-12-05 7 views
1

Я нашел этот пример о Iterable для Non-Iterable картографирования с использованием Классификатора:MapStruct: Вложенные итерации на нетерабельное отображение?

https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-iterable-to-non-iterable

Но как сделать это отображение в состоянии отобразить вложенные свойства (используя точечную аннотацию)?

E.g. сопоставление поля xyz первого элемента коллекции в исходном объекте с простым полем на целевом объекте?

Пример определения Классификатор

@Qualifier 
@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.SOURCE) 
public @interface FirstElement { 
} 

затем определить настраиваемого Mapper

public class MapperUtils { 
    @FirstElement 
    public <T> T first(List<T> in) { 
     if (in != null && !in.isEmpty()) { 
      return in.get(0); 
     } 
     else { 
      return null; 
     } 
    } 
} 

и, наконец, отображение определяется как

@Mapping(target = "emailaddress", source = "emails", qualifiedBy = FirstElement.class) 

Но если я хотел бы извлечение из первого элемента коллекции электронных писем определенного поля, например как я бы сделал с кодом emails.get(0).getEmailAddress?

Например, я ожидаю, чтобы написать отображение, как это:

@Mapping(target = "emailaddress", source = "emails[0].emailAddress") 

ответ

2

Вам просто нужно изменить MapperUtils

public class MapperUtils { 
    @FirstElement 
    public String firstEmailAddress(List<Person> in) { 
     if (in != null && !in.isEmpty()) { 
      return in.get(0).getEmailAddress(); 
     } 
     else { 
      return null; 
     } 
    } 
} 

В основном параметр аннотированному метод должен иметь Iterable, что вы хотите отобразить карту, а тип возврата должен быть Non-Iterable, на который вы хотите установить карту.

Если вы не хотите создавать настраиваемое сопоставление для сопоставления, альтернативой является использование атрибута expression.

Например:

@Mapping(target = "emailaddress", expression = "emails != null && !emails.isEmpty() ? emails.get(0).getEmailAddress() : null") 

Однако, будьте осторожны, используя выражение может привести к компиляции проблемы со временем, если вы сделаете ошибку. MapStruct не проверяет правильность выражения и использует его как есть.

+0

Да, я знаю, но с этим решением я должен реализовать метод для каждого конкретного типа, содержащегося в Iterable. Я хотел бы получить первый элемент, а затем получить доступ к полю этого типа с помощью точечной нотации. Так что я хотел бы написать что-то вроде этого: @Mapping (цель = "EMAILADDRESS", источник = "emails.emailAddress", qualifiedBy = FirstElement.class) но @Mapping (цель = "префикс" , источник = "phoneNumbers.prefix", qualifiedBy = FirstElement.class) без написания метод для каждого свойства отображается – lincetto

+0

Например, я хотел бы написать Mapper так: @Mapping (цель = "EMAILADDRESS", источник = "email [0] .emailAddress") – lincetto

+0

Вы правы. Есть еще один способ, которым вы можете это сделать. Вы можете использовать атрибут 'expression'' @ Maping'. Например, '@Mapping (target =" emailaddress ", выражение =" emails! = Null &&! Emails.isEmpty()? Emails.get (0) .getEmailAddress(): null "}'.Вы можете использовать 'электронные письма', если они являются частью метода сопоставления, если' emails' является атрибутом исходного параметра, тогда вам придется делать 'source.getEmails()' – Filip

 Смежные вопросы

  • Нет связанных вопросов^_^