首页 > 解决方案 > 自动映射除一个以外的所有字段,该字段应通过其他函数传递

问题描述

使用 Mapstruct,我如何创建一个映射器,它会自动映射除一个(或两个、三个等)字段之外的所有字段,这些字段应该通过一些自定义映射逻辑传递?

映射器

@Mapper
public interface MyEntityMapper
{
    MyEntityMapper INSTANCE = Mappers.getMapper(MyEntityMapper.class);

    @Mappings(
        {
            @Mapping(source = "createdByPerson.id", target = "createdByPersonId"),
        })
    MyEventPayload toEventPayload(MyEntity entity);
}

如果我有一个someString字段需要先完成一些自定义映射日志记录,我该怎么做?我看到了这个argument选项@Mapping,但是在注释中的字符串中编写 java 代码似乎有点疯狂!

我希望做类似的事情:

@MappingFor(MyEntity.class, "someString")
default String mapSomeString(String value) {
    return value + " custom mapping ";
}

更新

我找到@AfterMapping并使用了它,例如:

@AfterMapping
public void mapSomeString(MyEntity entity, MyEventPayload payload) {
    // do fancy stuff here
}

但是我仍然很好奇您是否可以提供每个字段的映射后/自定义映射功能。

标签: javamapstruct

解决方案


如果您想以特定方式映射单个字段,您可以使用基于限定符的映射方法选择

这看起来像

@Mapper
public interface MyEntityMapper {

    @Mapping(target = "someString", qualifiedByName = "myFancyMapping")
    MyEventPayload toEventPayload(MyEntity entity);

    @Named("myFancyMapping") // org.mapstruct.Named
    default String mapSomeString(String value) {
        return value + " custom mapping ";
    }
}

您还可以使用Mapping#qualifiedBy和构建自己的Qualifier( org.mapstruct.Qualifier) 注释。

这看起来像:

@Qualifier // org.mapstruct.Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface MyFancyMapping {
}

@Mapper
public interface MyEntityMapper {

    @Mapping(target = "someString", qualifiedBy = MyFancyMapping.class)
    MyEventPayload toEventPayload(MyEntity entity);

    @MyFancyMapping
    default String mapSomeString(String value) {
        return value + " custom mapping ";
    }
}

选择

另一种方法是在表达式中@AfterMapping或使用表达式进行自定义映射(我不建议使用表达式,因为它容易出错)。


推荐阅读