指定第三级映射器的多个源字段

发布于 2025-02-07 07:52:57 字数 1395 浏览 4 评论 0原文

示例

public class Source {
    String fromPersonFirstName;
    String fromPersonLastName;
    String toPersonFirstName;
    String toPersonLastName;
    String message;
}

public class Target {
    Person from;
    Person to;
    String message;

}

public class Person {
    String firstName;
    String lastName;
}

@Mapper(componentModel = "spring")
public interface PersonMapper {
    Person toPerson(String firstName, String lastName);
}

现在对问题

进行了对象,采用尽可能多的映射方式是什么干净的方式?不使用表情?

理想情况下,我会告诉MapStruct进行以下操作

@Mapper(componentModel = "spring", uses = PersonMapper.class)
public interface ExampleMapper {

    @Mapping(target = "from", source = "fromPersonFirstName, fromPersonLastName")
    @Mapping(target = "to", source = "toPersonFirstName, toPersonLastName")
    Target toTarget(Source s);
}

,我可以注释shorsMappertoperson,然后对于totarget method code> filect> filect> filesifiedbyname ='' theclassNameValue,themEthodNameValue“ 。但是我仍然不知道如何告诉使用哪种源字段使用。

还有什么选择?我可以使用本地方法topersonfilesifiedbyname。但是,我必须以某种方式导入其他映射器。也许更改exipplemapper以抽象并自动自动映射。但是我仍然无法指定多个字段。

我知道表达式可能是为了填补此空白。但是...如果可能的话,我宁愿永远不会使用它。除非替代方案要复杂得多。

Sample Objects

public class Source {
    String fromPersonFirstName;
    String fromPersonLastName;
    String toPersonFirstName;
    String toPersonLastName;
    String message;
}

public class Target {
    Person from;
    Person to;
    String message;

}

public class Person {
    String firstName;
    String lastName;
}

@Mapper(componentModel = "spring")
public interface PersonMapper {
    Person toPerson(String firstName, String lastName);
}

The Question

Now, what would be a clean way of employing as much as mapstruct as possible? Without using expressions?

Ideally I'd tell mapstruct to do the following

@Mapper(componentModel = "spring", uses = PersonMapper.class)
public interface ExampleMapper {

    @Mapping(target = "from", source = "fromPersonFirstName, fromPersonLastName")
    @Mapping(target = "to", source = "toPersonFirstName, toPersonLastName")
    Target toTarget(Source s);
}

Alternatively I could annotate PersonMapper and toPerson, then for the toTarget method qualifiedByName = "TheClassNameValue, TheMethodNameValue". But I still don't know how to tell the method which source fields to use.

What would be another option? I could use a local method toPerson, qualifiedByName. But then I'd have to import the other mapper in some way. Maybe change the ExampleMapper to abstract and autowire the other mapper. But I still can't specify multiple fields.

I know that expression is probably meant to fill in this gap. But ... I would rather never use it if possible. Unless the alternative is considerably more complicated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笨笨の傻瓜 2025-02-14 07:52:57

解决方案1,基于限定器的映射方法选择/a>

@Mapper
public interface ExampleMapper {
    @Mapping(target = "from", source = "source", qualifiedByName = "fromPersonMapping")
    @Mapping(target = "to", source = "source", qualifiedByName = "toPersonMapping")
    Target toTarget(Source source);

    @Named("fromPersonMapping")
    @Mapping(target = "firstName", source = "fromPersonFirstName")
    @Mapping(target = "lastName", source = "fromPersonLastName")
    Person fromPersonMapping(Source source);

    @Named("toPersonMapping")
    @Mapping(target = "firstName", source = "toPersonFirstName")
    @Mapping(target = "lastName", source = "toPersonLastName")
    Person toPersonMapping(Source source);
}

生成的代码:

public class ExampleMapperImpl implements ExampleMapper {

    @Override
    public Target toTarget(Source source) {
        if ( source == null ) {
            return null;
        }
        Target target = new Target();
        target.from = fromPersonMapping( source );
        target.to = toPersonMapping( source );
        target.message = source.message;
        return target;
    }

    @Override
    public Person fromPersonMapping(Source source) {
        if ( source == null ) {
            return null;
        }
        Person person = new Person();
        person.firstName = source.fromPersonFirstName;
        person.lastName = source.fromPersonLastName;
        return person;
    }

    @Override
    public Person toPersonMapping(Source source) {
        if ( source == null ) {
            return null;
        }
        Person person = new Person();
        person.firstName = source.toPersonFirstName;
        person.lastName = source.toPersonLastName;
        return person;
    }
}

与自定义方法的替代方案:

@Mapper
public interface ExampleMapper {
    @Mapping(target = "from", source = "source", qualifiedByName = "fromFieldsMapping")
    @Mapping(target = "to",  source = "source", qualifiedByName = "toFieldsMapping")
    Target toTarget(Source source);

    Person toPerson(String firstName, String  lastName);

    @Named("fromFieldsMapping")
    default Person fromFieldsMapping(Source source) {
        return toPerson(source.fromPersonFirstName, source.fromPersonLastName);
    }

    @Named("toFieldsMapping")
    default Person toFieldsMapping(Source source) {
        return toPerson(source.toPersonFirstName, source.toPersonLastName);
    }
}

生成的代码:

public class ExampleMapperImpl implements ExampleMapper {

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

        Target target = new Target();

        target.from = fromFieldsMapping( source );
        target.to = toFieldsMapping( source );
        target.message = source.message;

        return target;
    }

    @Override
    public Person toPerson(String firstName, String lastName) {
        if ( firstName == null && lastName == null ) {
            return null;
        }

        Person person = new Person();

        if ( firstName != null ) {
            person.firstName = firstName;
        }
        if ( lastName != null ) {
            person.lastName = lastName;
        }

        return person;
    }
}

单独的映射器:

@Mapper(uses = PersonMapper.class)
public interface ExampleMapper1 {
    @Mapping(target = "from", source = "source", qualifiedBy = FromAnnotation.class)
    @Mapping(target = "to", source = "source", qualifiedBy = ToAnnotation.class)
    Target toTarget(Source source);
}

@Mapper
public interface PersonMapper {
    Person toPerson(String firstName, String lastName);

    @FromAnnotation
    default Person fromFieldsMapping(Source source) {
        return toPerson(source.fromPersonFirstName, source.fromPersonLastName);
    }

    @ToAnnotation
    default Person toFieldsMapping(Source source) {
        return toPerson(source.toPersonFirstName, source.toPersonLastName);
    }
}

@Qualifier
@java.lang.annotation.Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface ToAnnotation {
}

@Qualifier
@java.lang.annotation.Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface FromAnnotation {
}

解决方案2,表达式

@Mapper
public interface ExampleMapper {
    @Mapping(target = "from", expression = "java(toPerson(source.fromPersonFirstName, source.fromPersonLastName))")
    @Mapping(target = "to", expression = "java(toPerson(source.toPersonFirstName, source.toPersonLastName))")
    Target toTarget(Source source);

    Person toPerson(String firstName, String  lastName);
}

生成的代码:

    @Override
    public Target toTarget(Source source) {
        if ( source == null ) {
            return null;
        }
        Target target = new Target();
        target.message = source.message;
        target.from = toPerson(source.fromPersonFirstName, source.fromPersonLastName);
        target.to = toPerson(source.toPersonFirstName, source.toPersonLastName);
        return target;
    }

    @Override
    public Person toPerson(String firstName, String lastName) {
        if ( firstName == null && lastName == null ) {
            return null;
        }
        Person person = new Person();
        if ( firstName != null ) {
            person.firstName = firstName;
        }
        if ( lastName != null ) {
            person.lastName = lastName;
        }
        return person;
    }

解决方案3,常规映射

@Mapper
public interface ExampleMapper {
    @Mapping(target = "from.firstName", source = "source.fromPersonFirstName")
    @Mapping(target = "from.lastName", source = "source.fromPersonLastName")
    @Mapping(target = "to.firstName",  source = "source.toPersonFirstName")
    @Mapping(target = "to.lastName",  source = "source.toPersonLastName")
    Target toTarget(Source source);
}

生成的代码:

public class ExampleMapperImpl implements ExampleMapper {

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

        Target target = new Target();

        target.from = sourceToPerson( source );
        target.to = sourceToPerson1( source );
        target.message = source.message;

        return target;
    }

    protected Person sourceToPerson(Source source) {
        if ( source == null ) {
            return null;
        }

        Person person = new Person();

        person.firstName = source.fromPersonFirstName;
        person.lastName = source.fromPersonLastName;

        return person;
    }

    protected Person sourceToPerson1(Source source) {
        if ( source == null ) {
            return null;
        }

        Person person = new Person();

        person.firstName = source.toPersonFirstName;
        person.lastName = source.toPersonLastName;

        return person;
    }
}

Solution 1, Mapping method selection based on qualifiers

@Mapper
public interface ExampleMapper {
    @Mapping(target = "from", source = "source", qualifiedByName = "fromPersonMapping")
    @Mapping(target = "to", source = "source", qualifiedByName = "toPersonMapping")
    Target toTarget(Source source);

    @Named("fromPersonMapping")
    @Mapping(target = "firstName", source = "fromPersonFirstName")
    @Mapping(target = "lastName", source = "fromPersonLastName")
    Person fromPersonMapping(Source source);

    @Named("toPersonMapping")
    @Mapping(target = "firstName", source = "toPersonFirstName")
    @Mapping(target = "lastName", source = "toPersonLastName")
    Person toPersonMapping(Source source);
}

Generated code:

public class ExampleMapperImpl implements ExampleMapper {

    @Override
    public Target toTarget(Source source) {
        if ( source == null ) {
            return null;
        }
        Target target = new Target();
        target.from = fromPersonMapping( source );
        target.to = toPersonMapping( source );
        target.message = source.message;
        return target;
    }

    @Override
    public Person fromPersonMapping(Source source) {
        if ( source == null ) {
            return null;
        }
        Person person = new Person();
        person.firstName = source.fromPersonFirstName;
        person.lastName = source.fromPersonLastName;
        return person;
    }

    @Override
    public Person toPersonMapping(Source source) {
        if ( source == null ) {
            return null;
        }
        Person person = new Person();
        person.firstName = source.toPersonFirstName;
        person.lastName = source.toPersonLastName;
        return person;
    }
}

Alternative with custom methods:

@Mapper
public interface ExampleMapper {
    @Mapping(target = "from", source = "source", qualifiedByName = "fromFieldsMapping")
    @Mapping(target = "to",  source = "source", qualifiedByName = "toFieldsMapping")
    Target toTarget(Source source);

    Person toPerson(String firstName, String  lastName);

    @Named("fromFieldsMapping")
    default Person fromFieldsMapping(Source source) {
        return toPerson(source.fromPersonFirstName, source.fromPersonLastName);
    }

    @Named("toFieldsMapping")
    default Person toFieldsMapping(Source source) {
        return toPerson(source.toPersonFirstName, source.toPersonLastName);
    }
}

Generated code:

public class ExampleMapperImpl implements ExampleMapper {

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

        Target target = new Target();

        target.from = fromFieldsMapping( source );
        target.to = toFieldsMapping( source );
        target.message = source.message;

        return target;
    }

    @Override
    public Person toPerson(String firstName, String lastName) {
        if ( firstName == null && lastName == null ) {
            return null;
        }

        Person person = new Person();

        if ( firstName != null ) {
            person.firstName = firstName;
        }
        if ( lastName != null ) {
            person.lastName = lastName;
        }

        return person;
    }
}

With separate mapper:

@Mapper(uses = PersonMapper.class)
public interface ExampleMapper1 {
    @Mapping(target = "from", source = "source", qualifiedBy = FromAnnotation.class)
    @Mapping(target = "to", source = "source", qualifiedBy = ToAnnotation.class)
    Target toTarget(Source source);
}

@Mapper
public interface PersonMapper {
    Person toPerson(String firstName, String lastName);

    @FromAnnotation
    default Person fromFieldsMapping(Source source) {
        return toPerson(source.fromPersonFirstName, source.fromPersonLastName);
    }

    @ToAnnotation
    default Person toFieldsMapping(Source source) {
        return toPerson(source.toPersonFirstName, source.toPersonLastName);
    }
}

@Qualifier
@java.lang.annotation.Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface ToAnnotation {
}

@Qualifier
@java.lang.annotation.Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface FromAnnotation {
}

Solution 2, Expression

@Mapper
public interface ExampleMapper {
    @Mapping(target = "from", expression = "java(toPerson(source.fromPersonFirstName, source.fromPersonLastName))")
    @Mapping(target = "to", expression = "java(toPerson(source.toPersonFirstName, source.toPersonLastName))")
    Target toTarget(Source source);

    Person toPerson(String firstName, String  lastName);
}

Generated code:

    @Override
    public Target toTarget(Source source) {
        if ( source == null ) {
            return null;
        }
        Target target = new Target();
        target.message = source.message;
        target.from = toPerson(source.fromPersonFirstName, source.fromPersonLastName);
        target.to = toPerson(source.toPersonFirstName, source.toPersonLastName);
        return target;
    }

    @Override
    public Person toPerson(String firstName, String lastName) {
        if ( firstName == null && lastName == null ) {
            return null;
        }
        Person person = new Person();
        if ( firstName != null ) {
            person.firstName = firstName;
        }
        if ( lastName != null ) {
            person.lastName = lastName;
        }
        return person;
    }

Solution 3, regular mapping

@Mapper
public interface ExampleMapper {
    @Mapping(target = "from.firstName", source = "source.fromPersonFirstName")
    @Mapping(target = "from.lastName", source = "source.fromPersonLastName")
    @Mapping(target = "to.firstName",  source = "source.toPersonFirstName")
    @Mapping(target = "to.lastName",  source = "source.toPersonLastName")
    Target toTarget(Source source);
}

Generated code:

public class ExampleMapperImpl implements ExampleMapper {

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

        Target target = new Target();

        target.from = sourceToPerson( source );
        target.to = sourceToPerson1( source );
        target.message = source.message;

        return target;
    }

    protected Person sourceToPerson(Source source) {
        if ( source == null ) {
            return null;
        }

        Person person = new Person();

        person.firstName = source.fromPersonFirstName;
        person.lastName = source.fromPersonLastName;

        return person;
    }

    protected Person sourceToPerson1(Source source) {
        if ( source == null ) {
            return null;
        }

        Person person = new Person();

        person.firstName = source.toPersonFirstName;
        person.lastName = source.toPersonLastName;

        return person;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文