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

Spring Boot中如何为Garage添加FreeSpots和BusySpots返回信息?

问题:Spring Boot中Garage DTO扩展空闲/占用车位字段的最优方案

我在Spring Boot中创建了Rest API,现有以下实体类和DTO类:

public class Garage {
    private Integer id;
    private String address;
    private Integer numberOfSpaces;
    private boolean accessLpg;
    private double width;
}

同时我还有:

public class GarageDto {
  private Integer id;
    private String address;
    private Integer numberOfSpaces;
    private boolean accessLpg;
    private double width;

public static GarageDto fromEntity(Garage garage) {
//INSIDE METHOD TO MAPPING FROM ENTITY TO DTO 
  }
}

我已存在Car实体类,需要在返回的Garage相关信息中添加FreeSpots(空闲车位)和BusySpots(占用车位)信息。我尝试了如下方案:

public class GarageDto {

    private Integer id;
    private String address;
    private Integer numberOfSpaces;
    private boolean accessLpg;
    private double width;
    private int freeSpaces;
    private int busySpaces;



    public static GarageDto fromEntity(Garage garage) {
        GarageDtoBuilder builder = GarageDto.builder()
                .id(garage.getId())
                .address(garage.getAddress())
                .numberOfSpaces(garage.getNumberOfSpaces())
                .accessLpg(garage.isAccessLpg())
                .width(garage.getWidth());

        if (garage.getCars() != null) {
            builder.freeSpaces(garage.getNumberOfSpaces() - garage.getCars().size())
                    .busySpaces(garage.getCars().size());
        } else {
            builder.freeSpaces(garage.getNumberOfSpaces())
                    .busySpaces(0);
        }

        return builder.build();
    }

}

但我认为该方案不够理想,想请教:是否需要新增类、将字段添加到GarageDto还是使用Mapper工具?求最优实现方案。


最优实现方案分析

1. 直接扩展现有GarageDto(优先推荐)

你的尝试方向没问题,直接在现有GarageDto里加freeSpaces和busySpaces是最简洁的方案,理由如下:

  • 这两个字段属于车库的衍生状态信息,和车库本身的基础属性(地址、车位总数等)强关联,放在同一个DTO里符合业务语义,前端调用接口时能一次性拿到所有需要的车库信息,无需额外请求。
  • 实现成本低,不需要新增类,只需要在原DTO中扩展字段,并完善映射逻辑即可。
  • 可以优化你当前的映射代码,简化空值判断:
    public static GarageDto fromEntity(Garage garage) {
        int carCount = garage.getCars() != null ? garage.getCars().size() : 0;
        return GarageDto.builder()
                .id(garage.getId())
                .address(garage.getAddress())
                .numberOfSpaces(garage.getNumberOfSpaces())
                .accessLpg(garage.isAccessLpg())
                .width(garage.getWidth())
                .busySpaces(carCount)
                .freeSpaces(garage.getNumberOfSpaces() - carCount)
                .build();
    }
    

2. 新增专用DTO(场景限定)

如果只有部分接口需要返回空闲/占用车位信息,大部分接口只需要车库基础属性,这时可以新增一个GarageWithSpacesDto继承GarageDto:

public class GarageWithSpacesDto extends GarageDto {
    private int freeSpaces;
    private int busySpaces;

    // 构造器、builder、映射方法
}

这种方式的好处是避免基础DTO被无关字段污染,适用于接口场景差异较大的情况,但会增加类的数量,维护成本略高。

3. 使用Mapper工具(长期维护推荐)

如果项目中存在大量实体和DTO的映射需求,推荐用MapStruct、ModelMapper这类工具替代手动映射:

  • MapStruct可以通过注解自动生成映射代码,减少手动编写的重复代码,避免出错:
    首先定义Mapper接口:
    @Mapper(componentModel = "spring")
    public interface GarageMapper {
        GarageMapper INSTANCE = Mappers.getMapper(GarageMapper.class);
    
        @Mapping(target = "busySpaces", expression = "java(garage.getCars() != null ? garage.getCars().size() : 0)")
        @Mapping(target = "freeSpaces", expression = "java(garage.getNumberOfSpaces() - (garage.getCars() != null ? garage.getCars().size() : 0))")
        GarageDto toDto(Garage garage);
    }
    
  • 好处是映射逻辑集中管理,后续字段变更时只需要修改注解,无需手动调整每个映射方法,适合中大型项目。

总结最优方案

  • 小项目/接口场景单一:直接扩展现有GarageDto,优化映射逻辑即可,简单高效。
  • 中大型项目/大量映射需求:使用MapStruct工具,减少重复代码,提升可维护性。
  • 接口场景差异大:新增专用DTO,避免基础DTO冗余。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 15:00:54