java 具有多个参数的 MapStruct QualifiedByName

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47694501/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 09:45:31  来源:igfitidea点击:

MapStruct QualifiedByName with multiple parameters

javaintellij-ideajava-8mapstruct

提问by Vivek Gupta

I have come across a situation where my mapping method has 3 parameters, and all the three are being used in deriving one of the properties of the target type.

我遇到过这样一种情况,我的映射方法有 3 个参数,并且所有三个参数都用于派生目标类型的属性之一。

I have created a default mapping method in the interface keeping the logic for deriving the property, now for calling this method, I could use an expression = "java( /*method call here*/ )"in the @Mappingannotation.

我在接口中创建了一个默认映射方法,保留派生属性的逻辑,现在为了调用这个方法,我可以expression = "java( /*method call here*/ )"@Mapping注释中使用 an 。

Is there any way to do this with any of the mapstruct annotation like @qualifiedByName, I tried commenting the annotation having expression property and used qualifiedByName, but it doesn't work :

有什么方法可以使用任何 mapstruct 注释来做到这一点,例如@qualifiedByName,我尝试评论具有表达式属性的注释并使用了qualifiedByName,但它不起作用:

@Mapper
public interface OneMapper {

    @Mapping(target="id", source="one.id")
    //@Mapping(target="qualified",expression = "java( checkQualified (one, projId, code) )")
    @Mapping(target="qualified",qualifiedByName="checkQualifiedNamed")
    OneDto createOne (One one, Integer projId, Integer val, String code);

    @Named("checkQualifiedNamed")
    default Boolean checkQualified (One one, Integer projId, Integer val, String code) {
        if(one.getProjectId() == projId && one.getVal() == val && one.getCode().equalsIgnoreCase(code)) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;                   
    }
}

回答by Filip

Currently MapStruct does not support mapping methods with multiple source properties.

目前 MapStruct 不支持具有多个源属性的映射方法。

However, in your case you can use the @Contextfrom 1.2.0. From what I understand the projIdand the codeare there just as helper of the mapping, and they are not used to map target properties from.

但是,在您的情况下,您可以使用@Contextfrom 1.2.0。据我所知,theprojId和 thecode只是映射的助手,它们不用于映射目标属性。

So you can do something like (It should work in theory):

所以你可以做一些类似的事情(理论上应该可以):

@Mapper
public interface OneMapper {

    @Mapping(target="id", source="one.id")
    @Mapping(target="qualified", qualifiedByName="checkQualifiedNamed")
    OneDto createOne (One one, @Context Integer projId, @Context String code);

    @Named("checkQualifiedNamed")
    default Boolean checkQualified (One one, @Context Integer projId, @Context String code) {
        if(one.getProjectId() == projId && one.getCode().equalsIgnoreCase(code)) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;                   
    }
}

Another alternative would be to extract all those properties into a separate class and pass that along (this would allow for multiple parameters of the same type).

另一种选择是将所有这些属性提取到一个单独的类中并将其传递(这将允许相同类型的多个参数)。

The class would look like:

这个类看起来像:

public class Filter {

    private final Integer projId;
    private final Integer val;
    private final String code;

    public Filter (Integer projId, Integer val, String code) {
        this.projId = projId;
        this.val = val;
        this.code = code;
    }

    //getters
}

Your mapper will then look like:

您的映射器将如下所示:

@Mapper
public interface OneMapper {

    @Mapping(target="id", source="one.id")
    @Mapping(target="qualified", qualifiedByName="checkQualifiedNamed")
    OneDto createOne (One one, @Context Filter filter);

    @Named("checkQualifiedNamed")
    default Boolean checkQualified (One one, @Context Filter filter) {
        if(one.getProjectId() == filter.getProjId() && one.getVal() == filter.getVal() && one.getCode().equalsIgnoreCase(filter.getCode())) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;                   
    }
}

You can then call the mapper like: mapper.createOne(one, new Filter(projId, val, code));

然后你可以像这样调用映射器: mapper.createOne(one, new Filter(projId, val, code));

回答by Pim Hazebroek

Since version 1.2 it is supported: http://mapstruct.org/documentation/stable/reference/html/#mappings-with-several-source-parameters

从 1.2 版开始支持:http: //mapstruct.org/documentation/stable/reference/html/#mappings-with-several-source-parameters

For example like this:

例如像这样:

@Mappings({
  @Mapping(source = "person.description", target = "description"),
  @Mapping(source = "address.houseNo", target = "houseNumber")
})
DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address);