Как отображать объекты как поля с помощью mapstruct?

Мне нужно сопоставить множественные dto с объектами. Почти все из них имеют ссылку на другой, и я не знаю, как передать ссылку при сопоставлении dto.

Вот одна из бизнес-реализаций Address:

addressRepository.saveAll(dtos.stream()
                .map(addressMapper::asEntity)
                .collect(Collectors.toList())).stream()
                .map(addressMapper::asDto)
                .collect(Collectors.toList());

Вот картограф

    @Mappings({
            @Mapping(target="streetName", source="streetName"),
            @Mapping(target="streetNumber", source="streetNumber"),
            @Mapping(target="block", source="block"),
            @Mapping(target="floor", source="floor")

    })
    CsvBusinessData asDto(AddressEntity address);

    @InheritInverseConfiguration
    AddressEntity asAddressEntity(CsvBusinessData address);

Все разработчики читают из одного и того же dto, а затем сопоставляют их с dto и entites.

Вот для клиента внедрение:

customerRepository.saveAll(dtos.stream()
            .map( csvMapper::asCustomerEntity)

            .collect(Collectors.toList())).stream()
            .map(customerMapper::asDto)
            .collect(Collectors.toList()); 

И сопоставление, в котором мне нужна ссылка на сопоставленный объект адреса (объект моего клиента имеет поле типа адреса).

 @Mappings({
            @Mapping(target = "nom", source = "lastName"),
            @Mapping(target = "nd", source = "accountNumber"),
            @Mapping(target = "logo", source = "logo"),
            @Mapping(target = "address", source = "address"
            )

    })
    CsvBusinessData asDto(CustomerEntity customer);

    @InheritInverseConfiguration
    CustomerEntity asCustomerEntity(CsvBusinessData customer);

Большое спасибо.


person Hemesky    schedule 17.02.2020    source источник
comment
Предоставьте классы CustomerEntity, CsvBusinessData и AddressEntity, чтобы ваш вопрос был более понятным.   -  person Misha Lemko    schedule 19.02.2020


Ответы (1)


Во-первых, вам не нужно делать сопоставление для полей с одинаковыми именами, MapStruct сделает это за вас, например, блок-блок. 1) Ваши объекты связаны: вы можете использовать функциональность использования для связанных объектов.

@Mapper(uses = {AddressMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface CustomerMapper {
    @Mapping(target = "nom", source = "lastName")
    @Mapping(target = "nd", source = "accountNumber")
    @Mapping(target = "logo", source = "logo") // not needed as same name, delete it
    @Mapping(target = "address", source = "address") // not needed as same name, delete it
    CsvBusinessData asDto(CustomerEntity customer);

    @InheritInverseConfiguration
    CustomerEntity asCustomerEntity(CsvBusinessData customer);
}

@Mapper( unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface CustomerMapper {
    @Mapping(target="streetName", source="streetName") // not needed as same name, delete it
    @Mapping(target="streetNumber", source="streetNumber") // not needed as same name, delete it
    @Mapping(target="block", source="block") // not needed as same name, delete it
    @Mapping(target="floor", source="floor") // not needed as same name, delete it
    CsvBusinessData asDto(AddressEntity address);
}

2) Ваши объекты не связаны: вы можете решить свой случай, передав несколько объектов в качестве параметров. Но тогда у вас должны быть свои собственные методы для противоположного направления. Если у вас одинаковое имя поля в AddressEntity и CustomerEntity, просто укажите его address.streetName или customer.lastName.

@Mapping(target="streetName", source="streetName")// possibly not needed as same name
@Mapping(target="streetNumber", source="streetNumber")// possibly not needed as same name
@Mapping(target="block", source="block")// possibly not needed as same name
@Mapping(target="floor", source="floor")// possibly not needed as same name
@Mapping(target = "nom", source = "lastName")
@Mapping(target = "nd", source = "accountNumber")
@Mapping(target = "logo", source = "logo")// possibly not needed as same name
@Mapping(target = "address", source = "customer.address") // specified as you have parameter address
CsvBusinessData asDto(AddressEntity address, CustomerEntity customer);

@Mapping(target="streetName", source="streetName")// possibly not needed as same name
@Mapping(target="streetNumber", source="streetNumber")// possibly not needed as same name
@Mapping(target="block", source="block")// possibly not needed as same name
@Mapping(target="floor", source="floor")// possibly not needed as same name
AddressEntity asAddressEntity(CsvBusinessData businessData);

@Mapping(source = "nom", target = "lastName")
@Mapping(source = "nd", target = "accountNumber")
@Mapping(source = "logo", target = "logo")// possibly not needed as same name
@Mapping(source = "address", target = "address") // specified as you have parameter address
CustomerEntity asCustomerEntity(CsvBusinessData businessData);
person Misha Lemko    schedule 19.02.2020