如何在mapstruct中使用来自不同类的另一个映射

时间:2020-03-04 09:51:05

标签: java spring java-8 mapstruct

我想将模型对象映射到dto模型。我已经有一个对象的映射器。 如何在另一个类的另一个映射器中重用此映射器?

我有以下模特

@Getter
@AllArgsConstructor
@ToString
public class History {

  @JsonProperty("identifier")
  private final Identifier identifier;

@JsonProperty("submitTime")
private final ZonedDateTime submitTime;

@JsonProperty("method")
private final String method;

@JsonProperty("reason")
private final String reason;

@JsonProperty("dataList")
private final List<Data> dataList;

}

 @DynamoDBTable(tableName = "history")
 @Data
 @NoArgsConstructor
 public class HistoryDynamo {
    @DynamoDBRangeKey(attributeName = "submitTime")
    @DynamoDBTypeConverted(converter = ZonedDateTimeType.Converter.class)
    private ZonedDateTime submitTime;

    @DynamoDBAttribute(attributeName = "identifier")
    @NonNull
    private Identifier identifier;

    @DynamoDBAttribute(attributeName = "method")
    private String method;

     @DynamoDBAttribute(attributeName = "reason")
     private String reason;

     @DynamoDBAttribute(attributeName = "dataList")
     private List<Data> dataList;
 }

    @Data
    @DynamoDBDocument
    @NoArgsConstructor
    public class Identifier implements Serializable {

        @DynamoDBAttribute(attributeName = "number")
        private String number;

    @DynamoDBAttribute(attributeName = "cityCode")
    @NonNull
    private String cityCode;

    @DynamoDBAttribute(attributeName = "countryCode")
    @NonNull
    private String countryCode;

    @DynamoDBTypeConverted(converter = LocalDateType.Converter.class)
    private LocalDate mydate;
}

     @Data
     @EqualsAndHashCode
     @NoArgsConstructor
     @RequiredArgsConstructor
     @JsonInclude(JsonInclude.Include.NON_NULL)
     public class Identifier implements Serializable {

    @NonNull
    @lombok.NonNull
    @NotNull
    private String number;

    @NonNull
    @lombok.NonNull
    @NotNull
    private City city;

    @NonNull
    @lombok.NonNull
    @NotNull
    private Country country;

    @JsonDeserialize(using = LocalDateDeserializer.class)
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'Z'")
    @DateTimeFormat(pattern = "yyyy-MM-dd'Z'")
    @NonNull
    @lombok.NonNull
    @NotNull
    private LocalDate mydate;
}

这是我的映射

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.WARN, injectionStrategy = InjectionStrategy.CONSTRUCTOR, nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL)
public interface IdentifierMapper {

    IdentifierMapper MAPPER = Mappers.getMapper(IdentifierMapper.class);


    @Mappings({@Mapping(source = "identifier.number", target = "number"),
               @Mapping(source = "identifier.city.code", target = "cityCode"),
               @Mapping(source = "identifier.country.code", target = "countryCode"),
               @Mapping(source = "identifier.mydate", target = "mydate")})
    @Named("toIdentifierDynamo")
    myproject.entity.dynamo.Identifier toIdentifierDynamo(myproject.model.Identifier identifier);
}

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.WARN, injectionStrategy = InjectionStrategy.CONSTRUCTOR,
        nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL, uses = {IdentifierMapper.class})
public interface HistoryMapper {

    HistoryMapper MAPPER = Mappers.getMapper(HistoryMapper.class);

    @Mappings({@Mapping(source = "identifier", target = "identifier", qualifiedByName = "toIdentifierDynamo"),
              @Mapping(source = "method", target = "method"),
              @Mapping(source = "reason", target = "reason"),
              @Mapping(source = "timestamp", target = "timestamp")})
    HistoryDynamo toHistoryDynamo(History history);
}

我想将History映射到HistoryDynamo,并重用IdentifierMapper来映射HistoryDynamo中的对象之一。 如何在toHistoryDynamo中使用toIdentifierDynamo?

1 个答案:

答案 0 :(得分:3)

  • 首先,您不必在Spring中创建实例。你可以 只是Authowire您的Mapper。
  • 您不必为其中的第二个提供@Mapping批注 每个字段是否具有相同的名称。 Mapstruct会为您做到这一点。
  • 可以使用MapStruct映射器的uses参数来解决您的问题 HistoryMapper可以在@Mapper中使用注释参数uses = IdentifierMapper.class。它将对IdentifierMapper进行身份验证 HistoryMapper。默认情况下,它将通过字段执行。你可以改变它 同样在参数中:injectionStrategy = InjectionStrategy.CONSTRUCTOR和您可能就足够了 具有相同的字段名称(标识符),MapStruct应该实现 应该使用IdentifierMapper