使用 Mapstruct 将对象列表转换为长 ID 列表

Convert List of Objects to List of Long IDs using Mapstruct

我正在使用 MapStruct 将实体转换为 DTO。

我有一个实体 A 和实体 B 的列表:

public class A {
    List<B> bs;
}

我想在 ADto 中有一个 B id 列表 class:

public class ADto {
    List<Long> bIds;
}

您必须定义自定义映射方法。 (我不知道还有其他更简单的方法可以将自定义对象映射到 Lang)

反正这里是映射器

@Mapper
public interface AMapper {
    
    @Mapping(source = "bs", target = "bIds", qualifiedByName = "bToId")
    public ADto aToADto(A a);
    
    @Named("bToId") 
    public static Long bToId(B b) { 
        return b.getId(); 
    }
}

基本上,第一种方法会使用您在其下方定义的方法(基于@Named 值)将 B 列表映射到 Longs

此方法类似于 taken by L_Cleo,但假设我们有更多(可能很多)用例,我们希望在这些用例中将实体映射到它们的 ID。如果您赞成我的回答,您可能也想给他们一个赞成票;我的回答受到了他们的启发。

首先,我们创建一个接口 HasId 并让所有具有 long getId() 方法的实体实现此接口:

public interface HasId {
  long getId();
}

@Builder
@Value
public class A implements HasId {
  long id;
  List<B> bs;
}


@Builder
@Value
public class B implements HasId {
  long id;
}

或者,如果我们已经有一个(抽象的)superclass 提供了一个 long getId() 方法,我们可以使用这个 class 来代替。它以相同的方式工作。

接下来,我们定义一个映射器,将 HasId 实体映射到它们的 id。 MapStruct 对此不提供任何支持,因此我们必须手动创建此映射器:

@Mapper
public class HasIdMapper {
  final long toId(HasId entity) {
    return entity.getId();
  }
}

我们像往常一样定义我们的Dto-class:

@Builder
@Value
public class ADto {
  List<Long> bIds;
}

最后我们定义映射器从AADto:

@Mapper(uses = HasIdMapper.class)
public interface AMapper {
  @Mapping(source = "bs", target = "bIds")
  ADto toDto(A entity);
}

这里重要的一点是 uses 属性,我们用它触发 HasIdMapper.

的使用

为了完整起见,这里有一个小测试用例:

  public static void main(String... args) {
    final A a = A.builder()
        .bs(List.of(
            B.builder().id(1).build(),
            B.builder().id(2).build(),
            B.builder().id(3).build()))
        .build();
    final ADto dto = Mappers.getMapper(AMapper.class).toDto(a);
    System.out.println(dto);
  }

这将打印出:

ADto(bIds=[1, 2, 3])