3

考虑 6 个 POJO 类:3 个 DAO 和 3 个 DTO。

DAO:“A”、“B”、“C”
DTO:“一”、“二”、“三”

public class A {

    private int idOfA;
    private String name;
    private List<B> b;

    // getters, setters, etc...
}

public class B {

    private int idOfB;
    private String name;
    private List<C> c;

    // getters, setters, etc...
}

public class C {

    private int idOfC;
    private String name;

    // getters, setters, etc...
}



public class One {

    private int id;
    private String name;
    private List<Two> two;

    // getters, setters, etc...
}

public class Two {

    private int id;
    private String name;
    private List<Three> Three;

    // getters, setters, etc...
}

public class Three {

    private int id;
    private String name;

    // getters, setters, etc...
}

“A”包含一个“B”列表。“B”包含一个“C”列表。
“One”包含“Two”的列表。“二”包含“三”的列表。

“A”通过“A2One”映射到“One”。“B”通过“B2Two”映射到“Two”。“C”通过“C2Three”映射到三。

public class A2One extends PropertyMap<A, One> {

    @Override
    protected void configure() {
        map().setId(source.getIdOfA());
        map().setName(source.getName());

        when(Conditions.isNotNull()).using(new BListConverter()).map(source.getBs()).setTwos(null);
    }
}

public class BListConverter extends AbstractConverter<List<B>, List<Two>> {

        @Override
        protected List<Two> convert(List<B> source) {

            List<Two> twos = new ArrayList<Two>(source.size());

            for(B b : source) {
                Two t = new Two();
                t.setId(b.getId());
                t.setName(b.getName());

                // Ignore list of Cs contained in B for now

                twos.add(t);
            }

            return twos;
        }
}

public class B2Two extends PropertyMap<B, Two> {

    @Override
    protected void configure() {
        map().setId(source.getIdOfB());
        map().setName(source.getName());

        when(Conditions.isNotNull()).using(new CListConverter()).map(source.getCs()).setThrees(null);
    }
}

B2Two 和 C2Three 的代码与 A2One 非常相似。

所以这是我的问题:

目前,“A”和“One”中包含的列表之间的转换是通过自定义转换器完成的(并且它可以工作),但我正在重复 B2Two 应该执行的相同操作(将 Bs 映射到 Twos)。

当要映射列表时,是否有任何方法级联属性映射(A2One -> B2Two -> C2Three),而无需编写仅复制属性映射正在执行的转换器?

备选方案 1:使用泛型创建自定义List, List类型映射,该类型映射转发到正确的属性/类型映射。

备选方案 2:在 A2One 中使用以下列表

mapper.addMappings(new BList2TwoList());
when(Conditions.isNotNull()).withProvider(listProvider).map().setTwos(mapper.map(source.getBs(), List.class));

ListProvider 在哪里扩展 AbstractProvider 返回新的 ArrayList()

备选方案 3:???

有任何想法吗?网站上涉及更多映射问题的文档非常差,我不一定要寻找替代框架。如果提供替代方案,它们必须允许轻松重构(因此 Dozer 和 Orika 基本上已经淘汰)。

提前致谢

更新:截至撰写本文时,ModelMapper基本上已经死了,实际上并不支持列表或映射级联,因此您将被迫为每个也可以是列表的对象编写映射和转换器。
此外,我发现 Orika 通过扩展 MapperBase 具有重构友好的映射。此外,Orika 可以透明地处理单个 bean 和 bean 列表的映射(对这两种情况使用单个映射规则)。

更新 2:在 Orika 中,可以使用 CustomMapper 对集合进行双向深度嵌套映射。这可以创建双向映射实现,并允许它们级联到其他自定义映射器。A2One 将持有 B2Two 的一个实例,并在映射“A”中包含的“B”时透明地使用它。

4

2 回答 2

2

我以为我只是表明现在可以使用模型映射器来实现...

它确实支持列表(至少在 0.7.5 版上)。

执行此操作的 propertymap 如下所示:

public class A2One extends PropertyMap<A, One> {

    @Override
    protected void configure() {
        map().setId(source.getIdOfA());
        map().setName(source.getName());

        map(source.getB()).setOne(null);
    }
}
于 2016-02-03T11:26:06.783 回答
1

使用 Orika,我能够以一种简单友好的方式获得我需要的所有要求。

于 2015-01-21T12:54:32.620 回答