Mapstruct 如何从源对象的 2 个或多个字段构造目标对象?

Mapstruct how to construct a target object from 2 or more fields of the source object?

class PersonDTO {
  String name;
  String street;
  String city;
}
class Person {
  String name;
  Address address;
}
class Address {
  String street;
  String city;
}

@Mapper(componentModel = "spring")
interface Mapper {
  Person fromPersonDTO(PersonDTO dto);
}

我尝试使用 2 StringAddress 但它抛出

ambiguous property exception

.

我应该在映射器中添加什么来将 PersonDTOstreetcity 映射到 Address

更新:

@Mapper(componentModel = "spring")
interface Mapper {
  @Mapping(source = "street", target = "address.street")
  @Mapping(source = "city", target = "address.city")
  Person fromPersonDTO(PersonDTO dto);
}

以上映射器可以处理直接映射。 但是如果我想在创建 Address 对象时添加一些业务逻辑怎么办,

例如:

address.street = street.replaceAll(" ", "_"); 
address.city = cityDao.findByName(city).getId();

有没有办法达到这样的要求?

@Mapper(componentModel = "spring")
interface Mapper {

    @Mappings({
            @Mapping(source = "street", target = "address.street"),
            @Mapping(source = "city", target = "address.city")
    })
    Person fromPersonDTO(PersonDTO dto);
}

属性 name 只要具有相同的名称和嵌套级别,就应该自动映射

更新:

@Mapper(componentModel = "spring")
public abstract class Mapper {

    @Autowired
    private CityDAO cityDao;

    @Mappings({
            @Mapping(source = "street", target = "address.street"),
            @Mapping(source = "city", target = "address.city")
    })
    Person fromPersonDTO(PersonDTO dto);

    @AfterMapping
    void after(@MappingTarget Person person) {
        Address address = person.getAddress();
        if (address != null) {
            // additional null-checks might be required
            address.setStreet(address.getStreet().replaceAll(" ", "_")); 
            address.setCity(cityDao.findByName(address.getCity()).getId();
        }
    }
}

请注意,为了使用自动装配的 bean,映射器必须是 class,而不是接口