如何实现MapStruct自定义映射逻辑

Java工具MapStruct 是一个代码生成器,它基于定义好的映射接口自动生成数据转换代码。在大多数情况下,MapStruct 可以通过简单的配置自动完成对象之间的映射。然而,有时你可能需要自定义实现某些映射逻辑。MapStruct 提供了多种方式来实现这一点:

1. 使用表达式

你可以使用 @Mapping 注解的 expression 属性来指定一个自定义表达式。这适用于简单的转换。

@Mapper
public interface MyMapper {

    @Mapping(target = "targetField", expression = "java(customMethod(source.getSourceField()))")
    TargetType map(SourceType source);

    default String customMethod(String value) {
        // 自定义的转换逻辑
        return modifiedValue;
    }
}

2. 使用 qualifiedByNamequalifiedBy

这些注解允许你指定一个特定的方法来处理特定的字段映射。

@Mapper
public interface MyMapper {

    @Mapping(target = "targetField", qualifiedByName = "customConversion")
    TargetType map(SourceType source);

    @Named("customConversion")
    default String customConversionMethod(String value) {
        // 自定义转换逻辑
        return modifiedValue;
    }
}

3. 使用 @AfterMapping@BeforeMapping

这些注解可以用于在映射之前或之后添加自定义逻辑。

@Mapper
public interface MyMapper {

    @Mapping(target = "targetField", source = "sourceField")
    TargetType map(SourceType source);

    @AfterMapping
    default void afterMapping(SourceType source, @MappingTarget TargetType target) {
        // 在映射之后执行的自定义逻辑
        target.setSomeField(customValue);
    }
}

4. 使用抽象类代替接口

使用抽象类,你可以实现一些自定义的映射方法,同时让 MapStruct 处理其余的映射。

@Mapper
public abstract class MyMapper {

    @Mapping(target = "targetField", source = "sourceField")
    abstract TargetType map(SourceType source);

    protected String customMethod(String value) {
        // 自定义逻辑
        return modifiedValue;
    }
}

5. 组合使用多个 Mapper

有时你可能需要将多个映射器组合起来,以处理复杂的映射逻辑。

@Mapper(uses = {OtherMapper.class})
public interface MyMapper {
    TargetType map(SourceType source);
}

在这种情况下,MyMapper 可以使用 OtherMapper 中定义的映射方法。

通过这些方法,你可以在 MapStruct 中实现复杂的映射逻辑,同时仍保持大部分映射的自动化和类型安全。这些自定义实现的方法提高了 MapStruct 的灵活性,使其能够适应各种不同的映射需求。