You need to enable JavaScript to run this app. 将实体List映射为DTO List时如何通过表达式或自定义方法指定DTO属性映射规则
优惠活动
大模型
产品
解决方案
定价
更多

将实体List映射为DTO List时如何通过表达式或自定义方法指定DTO属性映射规则

实现方案

MapStruct本身原生支持集合映射方法自动复用对应单元素映射的所有逻辑,你只需要调整列表映射方法的入参即可:

具体修改步骤

  • 第一步:给列表映射方法补充userId入参,和单元素映射方法的第二个参数保持一致
  • 第二步:删除列表映射方法上的@Mapping注解,集合映射不需要单独配置字段映射,会自动继承单元素方法的所有映射规则

修改后的代码如下:

@Mapping(target = "courseId", source = "resource.course.id")
@Mapping(target = "favoured", expression = "java(isResourceFavoured(resource, userId))")
public abstract ResourceDto resourceToResourceDto(Resource resource, Long userId);

// 不需要加任何@Mapping注解,自动调用上面的单元素映射方法
public abstract List<ResourceDto> resourceToResourceDto(List<Resource> resources, Long userId);

public boolean isResourceFavoured(Resource resource, Long userId) {
    ApplicationUser user = userService.findApplicationUserById(userId);
    return resourceService.isFavoured(resource, user);
}

实现原理

MapStruct生成集合映射的实现代码时,会自动匹配当前Mapper中类型对应的单元素映射方法:当存在入参类型为Resource+Long、返回值为ResourceDto的方法时,集合方法会自动遍历所有元素,逐个调用该单元素方法完成转换,单元素方法上配置的字段映射规则、自定义表达式、自定义映射方法都会被完整复用,不需要额外配置。

生成的集合方法实现逻辑大致如下:

@Override
public List<ResourceDto> resourceToResourceDto(List<Resource> resources, Long userId) {
    if (resources == null) {
        return null;
    }
    List<ResourceDto> dtoList = new ArrayList<>(resources.size());
    for (Resource resource : resources) {
        // 直接调用你定义的单元素映射方法,所有逻辑都复用
        dtoList.add(resourceToResourceDto(resource, userId));
    }
    return dtoList;
}

原有代码问题说明

你之前给列表方法加的@Mapping(target = "courseId", source = "course.id")是无效的,因为集合类型List<Resource>本身不存在course属性,编译时会提示字段找不到错误,直接删除即可。

内容的提问来源于stack exchange,提问作者josef

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 04:15:03