MapStruct 似乎创建了太多方法
MapStruct seems to create too many method
我正在使用 MapStruct v 1.4。1.Final 将 Hibernate 实体映射到相应的 DTO。我正在使用 Spring 启动,所以我的映射器的 classes 的 componentModel
等于 spring
.
我有 2 个实体,Person
和 Address
。 Person
包含一个 Address
实例:
人
public class Person {
private String username;
private String name;
private Address address;
}
public class PersonDto {
private String id;
private String name;
private AddressDto address;
private String role;
}
地址
public class Address {
private String addr;
private String city;
}
public class AddressDto {
private String houseAddress;
private String city;
}
这是我写的映射器:
映射器
@Mapper(componentModel = "spring")
public interface AddressMapper {
@Mapping(source="person.username", target="userName")
@Mapping(source="address.addr", target="address")
DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address);
@Mapping(source="person.username", target="userName")
@Mapping(source="person.address.addr", target="address")
DeliveryAddressDto personToDeliveryAddressDto(Person person);
@Mapping(source = "address.addr", target = "houseAddress")
AddressDto addressToAddressDto(Address address);
@InheritInverseConfiguration(name = "addressToAddressDto")
Address addressDtoToAddress(AddressDto addressDto);
}
@Mapper(componentModel = "spring", uses = {AddressMapper.class})
public interface PersonMapper {
@Mapping(source = "id", target = "username")
@Mapping(source = "address.houseAddress", target = "address.addr")
@Mapping(source = "role", target = "role.id")
Person toPerson(PersonDto personDto);
List<Person> toPeople(List<PersonDto> personDtos);
@InheritInverseConfiguration(name = "toPerson")
PersonDto toPersonDto(Person person);
List<PersonDto> toPeopleDto(List<Person> people);
/**
* update an existing Person with Dto info.
* Set infos on the existing object (Person), without creating a new one.
*/
@Mapping(source = "role", target = "role.id")
void updatePersonFromDto(PersonDto personDto, @MappingTarget Person person);
}
在那里你可以看到我对 PersonMapper
说要使用 AddressMapper
来使用它的实现。
然而,对于地址到地址 dto 的转换,我在 PersonMapper
class 中找到了另一个实现(与逆映射相同):
AddressMapper 实现
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2020-11-21T15:44:55+0100",
comments = "version: 1.4.1.Final, compiler: javac, environment: Java 11 (Oracle Corporation)"
)
@Component
public class AddressMapperImpl implements AddressMapper {
@Override
public DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address) {
if ( person == null && address == null ) {
return null;
}
DeliveryAddressDto deliveryAddressDto = new DeliveryAddressDto();
if ( person != null ) {
deliveryAddressDto.setUserName( person.getUsername() );
}
if ( address != null ) {
deliveryAddressDto.setAddress( address.getAddr() );
}
return deliveryAddressDto;
}
@Override
public DeliveryAddressDto personToDeliveryAddressDto(Person person) {
if ( person == null ) {
return null;
}
DeliveryAddressDto deliveryAddressDto = new DeliveryAddressDto();
deliveryAddressDto.setUserName( person.getUsername() );
deliveryAddressDto.setAddress( personAddressAddr( person ) );
return deliveryAddressDto;
}
@Override
public AddressDto addressToAddressDto(Address address) {
if ( address == null ) {
return null;
}
AddressDto addressDto = new AddressDto();
addressDto.setHouseAddress( address.getAddr() );
addressDto.setCity( address.getCity() );
return addressDto;
}
@Override
public Address addressDtoToAddress(AddressDto addressDto) {
if ( addressDto == null ) {
return null;
}
Address address = new Address();
address.setAddr( addressDto.getHouseAddress() );
address.setCity( addressDto.getCity() );
return address;
}
private String personAddressAddr(Person person) {
if ( person == null ) {
return null;
}
Address address = person.getAddress();
if ( address == null ) {
return null;
}
String addr = address.getAddr();
if ( addr == null ) {
return null;
}
return addr;
}
}
PersonMapper 实现
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2020-11-21T15:44:55+0100",
comments = "version: 1.4.1.Final, compiler: javac, environment: Java 11 (Oracle Corporation)"
)
@Component
public class PersonMapperImpl implements PersonMapper {
@Autowired
private AddressMapper addressMapper;
@Override
public Person toPerson(PersonDto personDto) {
if ( personDto == null ) {
return null;
}
Person person = new Person();
person.setAddress( addressDtoToAddress1( personDto.getAddress() ) );
person.setRole( personDtoToRole( personDto ) );
person.setUsername( personDto.getId() );
person.setName( personDto.getName() );
return person;
}
@Override
public List<Person> toPeople(List<PersonDto> personDtos) {
if ( personDtos == null ) {
return null;
}
List<Person> list = new ArrayList<Person>( personDtos.size() );
for ( PersonDto personDto : personDtos ) {
list.add( toPerson( personDto ) );
}
return list;
}
@Override
public PersonDto toPersonDto(Person person) {
if ( person == null ) {
return null;
}
PersonDto personDto = new PersonDto();
personDto.setAddress( addressToAddressDto1( person.getAddress() ) );
personDto.setId( person.getUsername() );
personDto.setRole( personRoleId( person ) );
personDto.setName( person.getName() );
return personDto;
}
@Override
public List<PersonDto> toPeopleDto(List<Person> people) {
if ( people == null ) {
return null;
}
List<PersonDto> list = new ArrayList<PersonDto>( people.size() );
for ( Person person : people ) {
list.add( toPersonDto( person ) );
}
return list;
}
@Override
public void updatePersonFromDto(PersonDto personDto, Person person) {
if ( personDto == null ) {
return;
}
if ( person.getRole() == null ) {
person.setRole( new Role() );
}
personDtoToRole1( personDto, person.getRole() );
person.setName( personDto.getName() );
person.setAddress( addressMapper.addressDtoToAddress( personDto.getAddress() ) );
}
protected Address addressDtoToAddress1(AddressDto addressDto) {
if ( addressDto == null ) {
return null;
}
Address address = new Address();
address.setAddr( addressDto.getHouseAddress() );
address.setCity( addressDto.getCity() );
return address;
}
protected Role personDtoToRole(PersonDto personDto) {
if ( personDto == null ) {
return null;
}
Role role = new Role();
role.setId( personDto.getRole() );
return role;
}
protected AddressDto addressToAddressDto1(Address address) {
if ( address == null ) {
return null;
}
AddressDto addressDto = new AddressDto();
addressDto.setHouseAddress( address.getAddr() );
addressDto.setCity( address.getCity() );
return addressDto;
}
private String personRoleId(Person person) {
if ( person == null ) {
return null;
}
Role role = person.getRole();
if ( role == null ) {
return null;
}
String id = role.getId();
if ( id == null ) {
return null;
}
return id;
}
protected void personDtoToRole1(PersonDto personDto, Role mappingTarget) {
if ( personDto == null ) {
return;
}
mappingTarget.setId( personDto.getRole() );
}
}
在此实现中,为什么要创建方法 addressDtoToAddress1()
?为什么不使用 AddressMapper
实现中提供的 addressDtoToAddress()
?这些方法是相同的。
另请注意,AddressMapper
是在 PersonMapper
中注入的,AddressMapper
的方法 addressDtoToAddress()
是在方法 updatePersonFromDto()
中调用的。
您在 PersonMapper
中指定了两次地址映射。
@Mapping(source = "id", target = "username")
@Mapping(source = "address.houseAddress", target = "address.addr")
Person toPerson(PersonDto personDto);
您声明 PersonMapper
应该使用 AddressMapper
,但您添加了另一个覆盖映射以手动映射字段。
您可以删除映射,它会自动找到正确的映射。
@Mapping(source = "id", target = "username")
Person toPerson(PersonDto personDto);
如果要添加显式映射,您需要选择源作为 PersonDto
的地址字段到目标 Person
的地址字段。下面将给出相同的结果。
@Mapping(source = "id", target = "username")
@Mapping(source = "address", target = "address")
Person toPerson(PersonDto personDto);
它在 updatePersonFromDto()
中工作正常,因为您没有添加它的覆盖并且它自己选择了 AddressMapper
。如果向其添加相同的冗余映射,您会注意到相同的行为。
我正在使用 MapStruct v 1.4。1.Final 将 Hibernate 实体映射到相应的 DTO。我正在使用 Spring 启动,所以我的映射器的 classes 的 componentModel
等于 spring
.
我有 2 个实体,Person
和 Address
。 Person
包含一个 Address
实例:
人
public class Person {
private String username;
private String name;
private Address address;
}
public class PersonDto {
private String id;
private String name;
private AddressDto address;
private String role;
}
地址
public class Address {
private String addr;
private String city;
}
public class AddressDto {
private String houseAddress;
private String city;
}
这是我写的映射器:
映射器
@Mapper(componentModel = "spring")
public interface AddressMapper {
@Mapping(source="person.username", target="userName")
@Mapping(source="address.addr", target="address")
DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address);
@Mapping(source="person.username", target="userName")
@Mapping(source="person.address.addr", target="address")
DeliveryAddressDto personToDeliveryAddressDto(Person person);
@Mapping(source = "address.addr", target = "houseAddress")
AddressDto addressToAddressDto(Address address);
@InheritInverseConfiguration(name = "addressToAddressDto")
Address addressDtoToAddress(AddressDto addressDto);
}
@Mapper(componentModel = "spring", uses = {AddressMapper.class})
public interface PersonMapper {
@Mapping(source = "id", target = "username")
@Mapping(source = "address.houseAddress", target = "address.addr")
@Mapping(source = "role", target = "role.id")
Person toPerson(PersonDto personDto);
List<Person> toPeople(List<PersonDto> personDtos);
@InheritInverseConfiguration(name = "toPerson")
PersonDto toPersonDto(Person person);
List<PersonDto> toPeopleDto(List<Person> people);
/**
* update an existing Person with Dto info.
* Set infos on the existing object (Person), without creating a new one.
*/
@Mapping(source = "role", target = "role.id")
void updatePersonFromDto(PersonDto personDto, @MappingTarget Person person);
}
在那里你可以看到我对 PersonMapper
说要使用 AddressMapper
来使用它的实现。
然而,对于地址到地址 dto 的转换,我在 PersonMapper
class 中找到了另一个实现(与逆映射相同):
AddressMapper 实现
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2020-11-21T15:44:55+0100",
comments = "version: 1.4.1.Final, compiler: javac, environment: Java 11 (Oracle Corporation)"
)
@Component
public class AddressMapperImpl implements AddressMapper {
@Override
public DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address) {
if ( person == null && address == null ) {
return null;
}
DeliveryAddressDto deliveryAddressDto = new DeliveryAddressDto();
if ( person != null ) {
deliveryAddressDto.setUserName( person.getUsername() );
}
if ( address != null ) {
deliveryAddressDto.setAddress( address.getAddr() );
}
return deliveryAddressDto;
}
@Override
public DeliveryAddressDto personToDeliveryAddressDto(Person person) {
if ( person == null ) {
return null;
}
DeliveryAddressDto deliveryAddressDto = new DeliveryAddressDto();
deliveryAddressDto.setUserName( person.getUsername() );
deliveryAddressDto.setAddress( personAddressAddr( person ) );
return deliveryAddressDto;
}
@Override
public AddressDto addressToAddressDto(Address address) {
if ( address == null ) {
return null;
}
AddressDto addressDto = new AddressDto();
addressDto.setHouseAddress( address.getAddr() );
addressDto.setCity( address.getCity() );
return addressDto;
}
@Override
public Address addressDtoToAddress(AddressDto addressDto) {
if ( addressDto == null ) {
return null;
}
Address address = new Address();
address.setAddr( addressDto.getHouseAddress() );
address.setCity( addressDto.getCity() );
return address;
}
private String personAddressAddr(Person person) {
if ( person == null ) {
return null;
}
Address address = person.getAddress();
if ( address == null ) {
return null;
}
String addr = address.getAddr();
if ( addr == null ) {
return null;
}
return addr;
}
}
PersonMapper 实现
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2020-11-21T15:44:55+0100",
comments = "version: 1.4.1.Final, compiler: javac, environment: Java 11 (Oracle Corporation)"
)
@Component
public class PersonMapperImpl implements PersonMapper {
@Autowired
private AddressMapper addressMapper;
@Override
public Person toPerson(PersonDto personDto) {
if ( personDto == null ) {
return null;
}
Person person = new Person();
person.setAddress( addressDtoToAddress1( personDto.getAddress() ) );
person.setRole( personDtoToRole( personDto ) );
person.setUsername( personDto.getId() );
person.setName( personDto.getName() );
return person;
}
@Override
public List<Person> toPeople(List<PersonDto> personDtos) {
if ( personDtos == null ) {
return null;
}
List<Person> list = new ArrayList<Person>( personDtos.size() );
for ( PersonDto personDto : personDtos ) {
list.add( toPerson( personDto ) );
}
return list;
}
@Override
public PersonDto toPersonDto(Person person) {
if ( person == null ) {
return null;
}
PersonDto personDto = new PersonDto();
personDto.setAddress( addressToAddressDto1( person.getAddress() ) );
personDto.setId( person.getUsername() );
personDto.setRole( personRoleId( person ) );
personDto.setName( person.getName() );
return personDto;
}
@Override
public List<PersonDto> toPeopleDto(List<Person> people) {
if ( people == null ) {
return null;
}
List<PersonDto> list = new ArrayList<PersonDto>( people.size() );
for ( Person person : people ) {
list.add( toPersonDto( person ) );
}
return list;
}
@Override
public void updatePersonFromDto(PersonDto personDto, Person person) {
if ( personDto == null ) {
return;
}
if ( person.getRole() == null ) {
person.setRole( new Role() );
}
personDtoToRole1( personDto, person.getRole() );
person.setName( personDto.getName() );
person.setAddress( addressMapper.addressDtoToAddress( personDto.getAddress() ) );
}
protected Address addressDtoToAddress1(AddressDto addressDto) {
if ( addressDto == null ) {
return null;
}
Address address = new Address();
address.setAddr( addressDto.getHouseAddress() );
address.setCity( addressDto.getCity() );
return address;
}
protected Role personDtoToRole(PersonDto personDto) {
if ( personDto == null ) {
return null;
}
Role role = new Role();
role.setId( personDto.getRole() );
return role;
}
protected AddressDto addressToAddressDto1(Address address) {
if ( address == null ) {
return null;
}
AddressDto addressDto = new AddressDto();
addressDto.setHouseAddress( address.getAddr() );
addressDto.setCity( address.getCity() );
return addressDto;
}
private String personRoleId(Person person) {
if ( person == null ) {
return null;
}
Role role = person.getRole();
if ( role == null ) {
return null;
}
String id = role.getId();
if ( id == null ) {
return null;
}
return id;
}
protected void personDtoToRole1(PersonDto personDto, Role mappingTarget) {
if ( personDto == null ) {
return;
}
mappingTarget.setId( personDto.getRole() );
}
}
在此实现中,为什么要创建方法 addressDtoToAddress1()
?为什么不使用 AddressMapper
实现中提供的 addressDtoToAddress()
?这些方法是相同的。
另请注意,AddressMapper
是在 PersonMapper
中注入的,AddressMapper
的方法 addressDtoToAddress()
是在方法 updatePersonFromDto()
中调用的。
您在 PersonMapper
中指定了两次地址映射。
@Mapping(source = "id", target = "username")
@Mapping(source = "address.houseAddress", target = "address.addr")
Person toPerson(PersonDto personDto);
您声明 PersonMapper
应该使用 AddressMapper
,但您添加了另一个覆盖映射以手动映射字段。
您可以删除映射,它会自动找到正确的映射。
@Mapping(source = "id", target = "username")
Person toPerson(PersonDto personDto);
如果要添加显式映射,您需要选择源作为 PersonDto
的地址字段到目标 Person
的地址字段。下面将给出相同的结果。
@Mapping(source = "id", target = "username")
@Mapping(source = "address", target = "address")
Person toPerson(PersonDto personDto);
它在 updatePersonFromDto()
中工作正常,因为您没有添加它的覆盖并且它自己选择了 AddressMapper
。如果向其添加相同的冗余映射,您会注意到相同的行为。