提问者:小点点

MapStruct:自定义映射函数应用于所有字段


我有一个自定义映射函数,它将int映射到String,但我只想在一个特殊情况下应用它。但是,它适用于所有int类型的源字段,而不仅仅是用java(…)注释的源字段。

源类:

class Source {
    private int a;
    private int b;
    // getters etc...
}

目标类别:

class Target {
    private String a;
    private String b;
    // getters etc...
}

映射器:

@Mapping(source="a", target="a") // should not be necessary, but to make it more explicit
@Mapping(target="b", expression = "java(modify(b))")
public abstract Target sourceToTarget(Source source);

String modify(int value) {
    return "prefix_" + value;
}

我想要实现的目标:

target.setA(String.valueOf(a));
target.setB(modify(b));

但是,生成的代码会执行以下操作:

target.setA(modify(a));
target.setB(modify(b));

删除表达式并进行修改时,映射结构对这两个值都使用字符串.valueOf。我尝试了地图结构1.4.2.最终以及1.5.2.最终。这两个类都使用龙目岛,但是,这在过去并不是一个问题。

这种行为是预期的吗?如果是的话,我还能怎么做?


共1个答案

匿名用户

有两种方法可以尝试:

--

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

    @Mapping(target = "b", expression = "java(modify(source.getB()))")
    @Mapping(target = "a", expression = "java(String.valueOf(source.getA()))")
    Target sourceToTarget(Source source);

    default String modify(int value) {
        return "prefix_" + value;
    }
}

它生成了以下代码:

@Component
public class ExampleMapperImpl implements ExampleMapper {

    @Override
    public Target sourceToTarget(Source source) {
        if ( source == null ) {
            return null;
        }

        Target target = new Target();

        target.setB( modify(source.getB()) );
        target.setA( String.valueOf(source.getA()) );

        return target;
    }
}

--

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

    @Mapping(source = "a", target = "a")
    @Mapping(target = "b", qualifiedByName = "any-name")
    Target sourceToTarget(Source source);

    @Named("any-name")
    default String modify(int value) {
        return "prefix_" + value;
    }
}

注意:我在< code>modify(int value)方法上使用了< code>@Named,因此它不能被任何映射使用,除非通过< code>qualifiedByName提到。

它生成了以下代码:

@Component
public class ExampleMapperImpl implements ExampleMapper {

    @Override
    public Target sourceToTarget(Source source) {
        if ( source == null ) {
            return null;
        }

        Target target = new Target();

        target.setA( String.valueOf( source.getA() ) );

        target.setB( modify(source.getB()) );

        return target;
    }
}