MapStruct эквивалент подсказки (Dozer)? - PullRequest
0 голосов
/ 01 ноября 2018

В Dozer мы можем упоминать интерфейсы в подсказке во время отображения поля. Как мы можем добиться того же в MapStruct?

Я не могу поставить здесь точный код. Но это похоже, как показано ниже. У нас есть пример класса домена:

Class A<T extends B> extends C<T>
{ 
     ...
 };

Где, B абстрактный класс. C - это класс, который содержит элемент List, который мы должны отобразить.

Похожая структура классов и интерфейсов на стороне DTO. Итак, отображение как показано ниже в Dozer:

<mapping>
 <class-a>Domain.A</class-a> 
 <class-b>DTO.A</class-b> 
 <field>
    <a>item</a>
    <b>item</b>
    <a-hint>Domain.B</a-hint>
    <b-hint>DTO.B</b-hint>
 </field>
</mapping>

В MapStruct как мы называем интерфейсы, как указано в подсказке в Dozer?

Сценарий: У нас есть:

public class ShopList<T extends Inp> extends Shop<T>\
{ ... };

где,

Inp - абстрактный класс без полей в нем, например:

public abstract class Inp() { };

Магазин такого класса, как:

public class Shop<T extends ShopInp> implements Serializbale 
{ private List<T> items = new ArrayList<T>(); 
//getters and setters for the items }; 

ShopInp - это публичный интерфейс без полей, например:

public interface ShopInp {} . 

У нас похожая структура классов на стороне DTO и на стороне домена.

Не могли бы вы дать мне знать, как будет выглядеть картограф для вышеуказанного сценария? В общем, если мы попытаемся отобразить класс ShopList, то как мы обеспечим, чтобы T расширяет ShopInp , а T расширяет Inp также отображаются как часть ShopList?

1 Ответ

0 голосов
/ 01 ноября 2018

Так называемые подсказки могут быть использованы через BeanMapping#resultType. MapStruct может использовать это для создания экземпляра объекта, который вы пытаетесь отобразить. Однако он создаст отображение только для элементов абстрактного класса, поскольку у него нет другой информации во время компиляции (Dozer использует отражение и может обнаруживать поля типа во время выполнения).

Представьте, что у вас есть эта структура

public interface Fruit {

    String getName();

    String setName(String name);

}

public Apple implements Fruit {

    ...
}

public Banana implements Fruit {

    ...

}

public abstract class FruitDto {

    private String name;

    //getters and setters

}

public AppleDto extends FruitDto {

    ...

}

public BananaDto extends FruitDto {

    ...

}

public class Basket {

    private Collection<Fruit> fruits;

}

public class BasketDto {

    private Collection<FruitDto> fruits;

}

Ваш картограф может выглядеть так:

@Mapper
public interface BasketMapper {

    BasketDto map(Basket basket);

    @BeanMapping(resultType = BananaDto.class)
    FruitDto map(Fruit fruit);

}

При использовании этого сопоставителя все фрукты в BasketDto будут иметь экземпляр BananaDto (из-за BeanMapping#resultType, и сопоставление будет создано только для элементов FruitDto

...