在两个方向上映射/展平嵌套属性

时间:2018-04-19 20:13:26

标签: java mapstruct

我有一个类似的实体类:

class SomeEntity {
  int id;
  string name;
  date created;
}

我有一个dto类,如:

class SomeDto {
   class SomeDtoAttributes {
      string name;
      date created;
   }

   string id;
   SomeDtoAttributes attributes;
}

基本上除了id之外,Entity上的所有属性都放在dto的attributes属性中。

我希望这个mapper可以重用于其他将遵循相同模式的实体/ dtos,但会有不同的属性。

我已阅读文档,但我不知道如何实现这一目标。目前我有类似的东西:

abstract class EntityMapper<DTO, DTOA E> {

    abstract E toEntity(DTO dto, DTOA attributes);

    abstract DTO toDto(E entity);

    abstract DTOA toDtoAttributes(E entity);

    abstract List<E> toEntityList(List<DTO> dtos);

    abstract List<DTO> toDtoList(List<E> entities);

    @AfterMapping
    protected void afterMapping(@MappingTarget DTO dto, E entity) {
        DTOA dtoAttributes = this.toDtoAttributes(entity);
        dto.setAttributes(dtoAttributes);
    }
}

但是我不喜欢我必须在dto方法中传递dtoAttributestoEntity,并且toEntityList方法不会填充返回实体的属性属性。

1 个答案:

答案 0 :(得分:0)

如果你的所有实体和dtos都是这样的话。你可以借助一些接口和泛型来实现这样的功能。

class SomeDto implements Dto<SomeDtoAttribute> {
   class SomeDtoAttributes implements DtoAttributes {
      String name;
      date created;
   }

   String id;
   SomeDtoAttributes attributes;
}

然后在你的映射器中你可以做

abstract class EntityMapper<DTO extends Dto<DTOA>, DTOA, E> {

    E toEntity(DTO dto) {
        E entity = toEntity(dto.getAttributes());
        if (entity != null) {
            entity.setId(dto.getId());
        }
        return entity;
    }

    @Mapping(target = "id", ignore = true)    
    abstract E toEntity(DTOA dtoAttributes);

    abstract DTO toDto(E entity);

    abstract DTOA toDtoAttributes(E entity);

    abstract List<E> toEntityList(List<DTO> dtos);

    abstract List<DTO> toDtoList(List<E> entities);

    @AfterMapping
    protected void afterMapping(@MappingTarget DTO dto, E entity) {
        DTOA dtoAttributes = this.toDtoAttributes(entity);
        dto.setAttributes(dtoAttributes);
    }
}