考虑6个POJO类:3个DAO和3个DTO。
DAOs: "A","B","C" DTOs: "One","Two","Three"
"A" 包含一个 "B" 列表,"B" 包含一个 "C" 列表。
"One" 包含一个 "Two" 列表,"Two" 包含一个 "Three" 列表。
"A" 通过 "A2One" 映射到 "One","B" 通过 "B2Two" 映射到 "Two","C" 通过 "C2Three" 映射到 "Three"。
DAOs: "A","B","C" DTOs: "One","Two","Three"
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" 列表,"Two" 包含一个 "Three" 列表。
"A" 通过 "A2One" 映射到 "One","B" 通过 "B2Two" 映射到 "Two","C" 通过 "C2Three" 映射到 "Three"。
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
创建自定义TypeMap,将其转发到正确的属性/类型映射。
备选方案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列表的映射(使用单个映射规则处理两种情况)。