You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot中MapStruct实现实体关联到DTO的映射问题

MapStruct集合转ID数组映射解决方案

针对你的Animal实体转AnimalResponse DTO的需求,无需手动循环,MapStruct可以通过Java表达式或自定义可复用方法实现集合到ID数组的映射,同时处理其他关联属性的ID提取,具体实现如下:

方案一:使用@Mapping表达式直接转换

修改AnimalMapper接口,添加字段映射规则:

@Mapper
public interface AnimalMapper extends BaseMapper<Animal, AnimalResponse> {
    AnimalMapper INSTANCE = Mappers.getMapper(AnimalMapper.class);

    @Override
    @Mapping(target = "animalTypes", expression = "java(animal.getAnimalTypes().stream().map(AnimalType::getId).toArray(Long[]::new))")
    @Mapping(target = "visitedLocations", expression = "java(animal.getVisitedLocations() != null ? animal.getVisitedLocations().stream().map(AnimalLocation::getId).toArray(Long[]::new) : null)")
    @Mapping(target = "chippedId", source = "chipperId.id")
    @Mapping(target = "chippingLocationId", source = "chippingLocationId.id")
    AnimalResponse toDto(Animal animal);
}

说明:

  • animalTypes:通过Stream API遍历List<AnimalType>,提取每个对象的id并转为Long[]
  • visitedLocations:增加空判断避免空指针异常,同样通过Stream提取id转数组
  • chippedId/chippingLocationId:直接映射关联对象的id字段到DTO对应属性

方案二:自定义可复用的转换方法

如果需要复用集合转ID数组的逻辑,可以定义默认方法配合@Named注解:

// 定义通用ID提取接口(用于统一处理有getId()方法的对象)
public interface HasId {
    Long getId();
}

// 让AnimalType和AnimalLocation实现HasId接口
public class AnimalType implements HasId {
    // 原有代码,确保getId()方法存在
}

public class AnimalLocation implements HasId {
    // 原有代码,确保getId()方法存在
}

// 修改Mapper接口
@Mapper
public interface AnimalMapper extends BaseMapper<Animal, AnimalResponse> {
    AnimalMapper INSTANCE = Mappers.getMapper(AnimalMapper.class);

    @Override
    @Mapping(target = "animalTypes", source = "animalTypes", qualifiedByName = "listToLongArray")
    @Mapping(target = "visitedLocations", source = "visitedLocations", qualifiedByName = "listToLongArray")
    @Mapping(target = "chippedId", source = "chipperId.id")
    @Mapping(target = "chippingLocationId", source = "chippingLocationId.id")
    AnimalResponse toDto(Animal animal);

    @Named("listToLongArray")
    default <T extends HasId> Long[] listToLongArray(List<T> list) {
        if (list == null) {
            return null;
        }
        return list.stream()
                .map(HasId::getId)
                .toArray(Long[]::new);
    }
}

说明:

  • 通用HasId接口让所有带id的实体类实现,实现转换逻辑复用
  • @Named注解标记自定义转换方法,@Mapping中通过qualifiedByName指定使用该方法
  • 若不想定义接口,可单独为AnimalType和AnimalLocation编写各自的转换方法,分别指定qualifiedByName

注意事项

  1. 确保MapStruct依赖正确配置(以Maven为例):
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.5.5.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.5.5.Final</version>
    <scope>provided</scope>
</dependency>
  1. 若Account的id类型为Long,而DTO中chippedId是Integer,需在表达式中转换:java(animal.getChipperId().getId().intValue())

内容的提问来源于stack exchange,提问作者Hankie-2

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 18:57:06