使用 ModelMapper 展平到 id 列表

Use ModelMapper to flatten to list of ids

我正在尝试使用 ModelMappermapcollection 个子对象到 list 个 ID 号。

public class Child {
    private int id;
    private String childName;
}

public class Parent {
    private Set<Child> children;
    private String parentName;
}

public class ParentDto {
    private int[] children; // Or use ArrayList<Integer>
    private String parentName;
}

如何告诉 ModelMapper 将 Child 对象集展平为 ID 号数组?

我的第一次尝试是这样的,但似乎不正确:

    modelMapper.addMappings(new PropertyMap<Parent, ParentDto>() {
        @Override
        protected void configure() {
            using(ctx -> ctx.getSource().stream().map(Parent::getId).collect(Collectors.toList())
                .map().setChildren(source.getId()));
        };
    });


    Type listType = new TypeToken<ArrayList<ParentDto>>() {}.getType();
    ArrayList<ParentDto> parentDtos = new ArrayList<>();
    parentDtos = modelMapper.map(parents, listType);

setChildren 调用似乎需要 map().add() 但这也不起作用。

欢迎提出想法。

实现此目的的一种方法是创建一个 Set<Child>int[] 转换器并使用它将 Parent.children 映射到 ParentDTO.children:

ModelMapper mapper = new ModelMapper();

Converter<Set<Child>, int[]> childSetToIntArrayConverter =
        ctx -> ctx.getSource()
                .stream()
                .mapToInt(Child::getId)
                .toArray();

mapper.createTypeMap(Parent.class, ParentDto.class)
        .addMappings(map -> map
                .using(childSetToIntArrayConverter)
                .map(
                        Parent::getChildren,
                        ParentDto::setChildren
                )
        );

这是完整的演示(使用 lombok 1.18.10 and modelmapper 2.3.5):

import lombok.AllArgsConstructor;
import lombok.Data;
import org.modelmapper.Converter;
import org.modelmapper.ModelMapper;

import java.util.Set;

public class Main {

    public static void main(String[] args) {

        Parent parent = new Parent();
        parent.setParentName("Parent");
        parent.setChildren(Set.of(
                new Child(1, "A"),
                new Child(2, "B"),
                new Child(3, "C")
        ));

        ModelMapper mapper = new ModelMapper();

        Converter<Set<Child>, int[]> childSetToIntArrayConverter =
                ctx -> ctx.getSource()
                        .stream()
                        .mapToInt(Child::getId)
                        .toArray();

        mapper.createTypeMap(Parent.class, ParentDto.class)
                .addMappings(map -> map
                        .using(childSetToIntArrayConverter)
                        .map(
                                Parent::getChildren,
                                ParentDto::setChildren
                        )
                );

        ParentDto dto = mapper.map(parent, ParentDto.class);

        System.out.println(parent);
        System.out.println(dto);
    }

    @Data
    @AllArgsConstructor
    public static class Child {
        private int id;
        private String childName;
    }

    @Data
    public static class Parent {
        private Set<Child> children;
        private String parentName;
    }

    @Data
    public static class ParentDto {
        private int[] children;
        private String parentName;
    }
}

输出

Main.Parent(children=[Main.Child(id=3, childName=C), Main.Child(id=2, childName=B), Main.Child(id=1, childName=A)], parentName=Parent)
Main.ParentDto(children=[3, 2, 1], parentName=Parent)