使用Org.ModelMapper进行条件映射((condition)?get-this:get-that)

时间:2018-08-07 11:57:06

标签: java modelmapper

我试图根据地图的根/源条件有条件地使用一个或另一个吸气剂。 A引用了B;但是,(引用)允许为空。当引用为 not null 时,我想使用其中的属性(B)。但是,当引用为空时,我想使用来源(A)中的属性。

这有点商业逻辑,但是我们的系统中有很多遵循这种模式的数据模型。使用映射器库将是有益的,在我看来,逻辑很简单-与使用库的Condition非常相似。

当我在getter中使用逻辑时,它将启动并初始化正常;但是,当该映射实际用于映射对象时,我从Model-Mapper获得了IllegalArgumentException的{​​{1}}。

我无法适当地将库的object is not an instance of declaring class放入解决方案中。它似乎更像是一劳永逸,而不是一个if-or-else。我有一个映射器,该映射器首先在源(Condition)上使用getter。然后,在下一行中,我调用条件A并映射Conditions.isNotNull())。因此,在我看来,它将首先使用a -> a.getB().getDescription()设置DTO的description属性。然后它将用A“覆盖”该值,但前提是a.getB().getDescription()不为空。但是,它似乎没有那样工作。相反,对于a.getB()返回null的实例,我将a.getB()视为DTO的null

总而言之,我希望能够执行以下操作:

description

这里有一些示例代码来演示我面临的问题。

modelMapper.createTypeMap(A.class, FlatAB.class).addMappings(mapper -> {
    mapper.map(a -> a.getB() != null ? a.getB().getDescription() : 
            a.getDescription(), FlatAB::setDescription);
});

2 个答案:

答案 0 :(得分:1)

I popped the question over on the library's Github,并得到了维护者Chun-Han, Hsiao的出色答复。

  

没有转换器,我们无法将多个源属性映射到目标。

     

请尝试:

modelMapper.addMappings(mapper ->
    mapper.using(ctx -> ctx.getSource().getB() != null
        ? ctx.getSource().getB().getDescription()
        : ctx.getSource().getDescription())
      .map(src -> src, FlatAB::setDescription));

我发现ctx.getSource()可能需要强制转换-但我敢肯定有一种方法可以填充类型。

答案 1 :(得分:0)

如果我正确理解了您的问题,我会像

Optional
    .ofNullable(a.getB())
    .map(B::getDescription)
    .orElseGet(a::getDescription)

如果b不为null,则将生成B描述,否则将生成A描述。

更新

将上面的代码放到单独的方法中将完成A.getMappingDescription()这样的技巧:

class A {
            String desc;
            B b;
            public String getMappingDescription() {
                return Optional
                        .ofNullable(getB())
                        .map(B::getDesc)
                        .orElse(desc);
            }
...
}

您的映射会更简单:

modelMapper.createTypeMap(A.class, FlatAB.class).addMapping(A::getMappingDescription, FlatAB::setDesc);

更新2

您可以简单地提取指定具体泛型的转换器,例如:

Converter<A, String> descriptionConverter = ctx -> ctx.getSource().getB() != null
        ? ctx.getSource().getB().getDesc()
        : ctx.getSource().getDesc();

mapper.using(descriptionConverter).map(src -> src, FlatAB::setDesc);

或显式转换为:

((Converter<A, String>) ctx -> ctx.getSource().getB()..