如何从 java 流中的接口调用 MapStruct 方法

How to call MapStruct method from interface in java stream

最近在一个项目中开始使用MapStruct映射工具。过去,为了映射 DTO -> 实体,反之亦然,我使用自定义映射器,例如:

public static CustomerDto toDto(Customer customer) {

    return isNull(customer)
        ? null
        : CustomerDto.builder()
            .id(customer.getId())
            .name(customer.getName())
            .surname(customer.getSurname())
            .phoneNumber(customer.getPhoneNumber())
            .email(customer.getEmail())
            .customerStatus(customer.getCustomerStatus())
            .username(customer.getUsername())
            .NIP(customer.getNIP())
            .build();
  }

万一我尝试获取一个可选对象,毕竟我能够通过以下方式将我的实体映射到 dto:

public Optional<CustomerDto> findOneById(final long id) {
    return customerRepository.findById(id).map(CustomerMapper::toDto);
  }

目前,正如我之前提到的,我正在使用 mapStruct,问题是我的映射器是,而不是 class,它的接口如下:

@Mapper
public interface CommentMapper {

  @Mappings({
      @Mapping(target = "content", source = "entity.content"),
      @Mapping(target = "user", source = "entity.user")
  })
  CommentDto commentToCommentDto(Comment entity);

  @Mappings({
      @Mapping(target = "content", source = "dto.content"),
      @Mapping(target = "user", source = "dto.user")
  })
  Comment commentDtoToComment(CommentDto dto);

}

我想知道是否有可能以某种方式在 stream gentle 中使用此接口方法来映射我的值而不包装值,例如:

public Optional<CommentDto> findCommentById(final long id) {

    Optional<Comment> commentById = commentRepository.findById(id);
    return Optional.ofNullable(commentMapper.commentToCommentDto(commentById.get()));
}

感谢您的帮助。

像这样访问映射器:

private static final YourMapper MAPPER = Mappers.getMapper(YourMapper.class);

final Optional<YourEntity> optEntity = entityRepo.findById(id);
return optEntity.map(MAPPER::toDto).orElse(null);

基本上我们对枚举做类似的事情

 @Mapping(target = "type", expression = "java(EnumerationType.valueOf(entity.getType()))")

您可以在@Mapping 注释中定义java 表达式

@Mapping(target = "comment", expression = "java(commentMapper.commentToCommentDto(commentRepository.findById(entity.commentId).orElse(null)))"

否则你应该可以使用

class CommentMapper { ... }

你可以自动引用

@Mapper(uses = {CommentMapper.class})

您的实现将检测 commentEntity 和 Dto 并将自动使用 CommentMapper。

MapStruct 映射器的工作方式如下:Shit in Shit out,所以请记住您的实体需要 commentEntity,以便 dto 可以具有 commentDto。

编辑

第二个解决方案可以使用:

@BeforeMapping
default void beforeMappingToDTO(Entity source, @MappingTarget Dto target) {
    target.setComment(commentMapper.commentToCommentDto(commentRepository.findById(entity.commentId).orElse(null)));
}

@Spektakulatius 的回答解决了一个问题。

为了达到目标我做了几个步骤: 首先,我创建了一个映射器对象以在 java 流中使用它:

private CommentMapper commentMapper = Mappers.getMapper(CommentMapper.class);

在最后一步中,我使用了对象 commentMapper,例如:

public Optional<CommentDto> findCommentById(final long id) {
    return commentRepository.findById(id).map(CommentMapper.MAPPER::commentToCommentDto);
}

毕竟这完全让我有可能在流中使用我的自定义 MapStruct 映射器。