如何使用MapStruct将含对象列表和单个对象的Model映射为Domain实体列表
MapStruct 列表附加公共参数映射实现方案
问题根因
你定义的多参数List转换方法无法生效的核心原因是:MapStruct默认不会自动将公共参数注入到列表每个元素的转换逻辑中,需要先显式定义单元素的双参数转换规则,再由List转换方法自动复用该规则。
实现步骤
1. 确认基础类定义
首先确保三类的字段符合你描述的结构:
// 源用户类 public class User { private int id; private String name; // 省略getter、setter、构造方法 } // 源公共国家信息类 public class CountryDetails { private String country; private String countryCode; // 省略getter、setter、构造方法 } // 目标类 public class DomainUser { private int id; private String name; private String country; private String countryCode; // 省略getter、setter、构造方法 }
2. 定义Mapper转换接口
核心是先声明单User转DomainUser的双参数方法,MapStruct会自动将该方法复用到列表转换的每个元素处理流程中,自动把公共的CountryDetails参数传递给每个元素的转换逻辑:
import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; import java.util.List; // 若使用Spring管理,添加componentModel = "spring"属性,否则不需要 @Mapper public interface UserConvertMapper { // 非Spring场景下添加实例声明,Spring场景下可删除该行直接注入Mapper UserConvertMapper INSTANCE = Mappers.getMapper(UserConvertMapper.class); // 单元素转换规则:字段名完全匹配时不需要手动加@Mapping注解 DomainUser toDomainUser(User user, CountryDetails countryDetails); // 列表转换方法:自动遍历User列表,每个元素调用上面的toDomainUser方法,传入公共的CountryDetails List<DomainUser> toDomainUserList(List<User> userList, CountryDetails countryDetails); }
3. 特殊场景适配
如果源和目标字段名不匹配,需要手动通过@Mapping指定映射关系,比如CountryDetails的code字段要映射到DomainUser的countryCode,则修改单元素转换方法:
@Mapping(source = "countryDetails.code", target = "countryCode") DomainUser toDomainUser(User user, CountryDetails countryDetails);
4. 调用示例
// 构造测试数据 CountryDetails country = new CountryDetails("中国", "CN"); List<User> users = List.of(new User(1, "张三"), new User(2, "李四")); // 调用转换(非Spring场景) List<DomainUser> result = UserConvertMapper.INSTANCE.toDomainUserList(users, country); // Spring场景下直接注入Mapper调用 // @Autowired // private UserConvertMapper userConvertMapper; // List<DomainUser> result = userConvertMapper.toDomainUserList(users, country);
最终输出的result列表中每个DomainUser都会包含对应User的id、name,以及统一的country、countryCode字段值。
内容的提问来源于stack exchange,提问作者Prashanth Billa
相关产品推荐
相关产品推荐

