mapstruct似乎创建了太多的方法

w3nuxt5m  于 2021-07-11  发布在  Java
关注(0)|答案(1)|浏览(427)

我使用mapstructv1.4.1.final将hibernate实体Map到相应的dto。我使用的是spring boot,所以我的mapper类 componentModel 等于 spring .
我有两个实体, 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;
}

下面是我写的Map:
Map器

@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 类(反向Map相同):

地址Map器实现

@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() 是否已创建?为什么不用这个 addressDtoToAddress() 提供于 AddressMapper 实施?这些方法是相同的。
另请注意 AddressMapper 注射在 PersonMapper 方法呢 addressDtoToAddress()AddressMapper 在方法中调用 updatePersonFromDto() .

x7rlezfr

x7rlezfr1#

您在中指定了两次地址Map PersonMapper .

@Mapping(source = "id", target = "username")
@Mapping(source = "address.houseAddress", target = "address.addr")
Person toPerson(PersonDto personDto);

你这么说 PersonMapper 应该使用 AddressMapper ,而是添加另一个覆盖Map来手动Map字段。
您只需删除Map,它就会自己找到正确的Map。

@Mapping(source = "id", target = "username")
Person toPerson(PersonDto personDto);

如果要添加显式Map,则需要选择源作为 PersonDto 的地址字段到目标 Person 的地址字段。下面将给出相同的结果。

@Mapping(source = "id", target = "username")
@Mapping(source = "address", target = "address")
Person toPerson(PersonDto personDto);

它在厨房里工作得很好 updatePersonFromDto() 因为你没有给它加上覆盖,它就把它取出来了 AddressMapper 它自己。如果向其添加相同的冗余Map,则会注意到相同的行为。

相关问题