有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Mapstruct通用映射器

我想知道在我的情况下如何避免干燥(不要重复):

我想要两个映射器:一个将Road转换为RoadWithLUPlaceDto,另一个将Road转换为RoadWithLUPlaceSmallDtoRoadWithLUPlaceSmallDto的字段比RoadWithloUnPlaceDto的字段少。我不想让两个接口具有相同的qualifiedByName逻辑方法

RoadWithLUPlaceSmallDto有一个字段RoadAddressSmallDto,而不是RoadAddressDto,所以我不能重用qualifiedByName标记的相同方法。我该怎么做?可能吗

@Mapper(componentModel = "spring")
public interface MyMapper {

    @Mapping(target = "lPlace", source = "road", qualifiedByName = "PointToLPlace")
    @Mapping(target = "uPlace", source = "road", qualifiedByName = "PointTouPlace")
    RoadWithloUnPlaceDto map(Road road);

//    @Mapping(target = "loadingPlace", source = "road", qualifiedByName = "SpotToLPlace")
//    @Mapping(target = "uPlace", source = "road", qualifiedByName = "SpotTouPlace")
//    RoadWithLUPlaceSmallDto mapToRoadWithLUPlaceSmallDto(road road);

    @Named("PointToLPlace")
    default RoadAddressDto mapLPlace(Road road) {
        return Optional.ofNullable(road)
                .map(road::getPoints)
                .filter(point -> !CollectionUtils.isEmpty(points))
                .flatMap(
                        points-> points.stream()
                                .sorted(Comparator.comparing(Point::getOrder))
                                .filter(point-> isAllowed(point.getOperations(), OperationType.L))
                                .findFirst()
                ).map(this::mapRoadAddress)
                .orElse(null);
    }
...

共 (1) 个答案

  1. # 1 楼答案

    MapStruct支持对@Mapping使用元注释。因此,在您的用例中,您可以执行以下操作:

    @Retention(RetentionPolicy.CLASS)
    @Mapping(target = "lPlace", source = "road", qualifiedByName = "PointToLPlace")
    @Mapping(target = "uPlace", source = "road", qualifiedByName = "PointTouPlace")    
    public @interface CommonRoadMapping { }
    

    然后在你的地图中使用它

    @Mapper(componentModel = "spring")
    public interface MyMapper {
    
        @CommonRoadMapping
        RoadWithloUnPlaceDto map(Road road);
    
        @CommonRoadMapping
        RoadWithLUPlaceSmallDto mapToRoadWithLUPlaceSmallDto(road road);
    
        @Named("PointToLPlace")
        default RoadAddressDto mapLPlace(Road road) {
            return Optional.ofNullable(road)
                    .map(road::getPoints)
                    .filter(point -> !CollectionUtils.isEmpty(points))
                    .flatMap(
                            points-> points.stream()
                                    .sorted(Comparator.comparing(Point::getOrder))
                                    .filter(point-> isAllowed(point.getOperations(), OperationType.L))
                                    .findFirst()
                    ).map(this::mapRoadAddress)
                    .orElse(null);
        }
    ...