MapStruct 多参数映射:如何正确将方法参数作为源字段绑定

在 mapstruct 中,当映射方法接收多个参数时,需通过 `@mapping(source = "paramname")` 显式指定非实体参数作为源值,而非使用 `qualifiedbyname`(该注解仅用于调用自定义命名转换方法)。

MapStruct 支持多源参数映射,但关键在于区分「源字段引用」与「自定义转换逻辑」。qualifiedByName 的作用是匹配带有 @Named("xxx") 注解的转换方法(如字符串截断、格式化等),它不用于选取方法参数作为映射源。若你想将第二个或第三个参数(如 String shortText)直接赋值给目标对象的嵌套属性(如 content.shortText),必须使用 source 属性,并确保参数名与 source 值严格一致(支持点号路径,但此处为顶层参数,无需前缀)。

✅ 正确写法如下:

@Mapper
public interface EntityMapper {
    @Mapping(target = "content.shortText", source = "shortText")
    @Mapping(target = "content.longText", source = "longText")
    EntityDto mapToDto(Entity entity, String shortText, String longText);
}

调用时:

EntityDto dto = mapper.mapToDto(myEntity, "Hello", "WorldLong");
// 结果:dto.getContent().getShortText() == "Hello"
//       dto.getContent().getLongText() == "WorldLong"

⚠️ 注意事项:

  • source 值必须与方法参数名完全相同(区分大小写),MapStruct 会自动识别并绑定;
  • 若参数是对象类型(如 User user),可使用点号访问其属性:source = "user.name";
  • qualifiedByName 仅适用于需要额外处理的场景,例如:
    @Named("shortText")
    public static String toShortText(String text) {
        return text != null ? text.substring(0, Math.min(50, text.length())) : null;
    }
    // 此时才配合 @Mapping(..., qualifiedByName = "shortText")
  • 确保目标属性 content 已被正确初始化(可通过 @BeanMapping(nullValuePropertyMappingStrategy = SET_TO_NULL) 或构造器/工厂方法控制)。

总结:多参数映射的核心是明确 source —— 它指向方法签名中的参数名;而 qualifiedByName 是转换策略的“路由开关”,二者职责不同,不可混用。