Map/Flatten 双向嵌套属性

Map/Flatten Nested Attributes in Both Directions

我有一个实体 class 比如:

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

我有一个 dto class 像:

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

   string id;
   SomeDtoAttributes attributes;
}

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

我希望此映射器可重复用于其他遵循相同模式但具有不同属性的 entities/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);
    }
}

但我不喜欢我必须在 toEntity 方法中同时传入 dtodtoAttributes,而 toEntityList 方法不在返回的实体上填充属性属性。

如果您所有的实体和 dto 都像这样。您可以借助一些接口和泛型来实现类似的目的。

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);
    }
}