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

Spring Boot接口改造:生成指定格式的嵌套JSON响应

改造Spring Boot+JPA分组统计返回JSON结构方案

1. 定义统计结果DTO

先创建用于接收分组统计结果的DTO,确保count为数值类型:

public class DataStatsDTO {
    private Integer year;
    private String name;
    private Long count;

    // 对应JPA查询字段顺序的构造方法
    public DataStatsDTO(Integer year, String name, Long count) {
        this.year = year;
        this.name = name;
        this.count = count;
    }

    // Getter方法
    public Integer getYear() { return year; }
    public String getName() { return name; }
    public Long getCount() { return count; }
}

2. 修改JPA Repository查询逻辑

用JPQL直接查询分组统计数据并映射到DTO,同时指定年份降序:

@Repository
public interface DataRepository extends JpaRepository<Data, Long> {
    @Query("SELECT new com.yourpackage.dto.DataStatsDTO(d.year, d.name, COUNT(d.id)) " +
           "FROM Data d GROUP BY d.year, d.name ORDER BY d.year DESC")
    List<DataStatsDTO> getGroupedStats();
}

3. 组装目标JSON结构

在Service层将查询结果按要求组装成嵌套结构,保证年份数值化且降序:

@Service
public class DataStatsService {
    @Autowired
    private DataRepository dataRepository;

    public Map<String, Object> getPrimeData() {
        List<DataStatsDTO> statsList = dataRepository.getGroupedStats();
        
        // 按年份分组,年份为数值型键,对应数据列表
        Map<Integer, List<Map<String, Object>>> yearGroupedData = statsList.stream()
            .collect(Collectors.groupingBy(
                DataStatsDTO::getYear,
                Collectors.mapping(dto -> {
                    Map<String, Object> item = new HashMap<>();
                    item.put("name", dto.getName());
                    item.put("count", dto.getCount()); // 已为数值型
                    return item;
                }, Collectors.toList())
            ));

        // 对年份键做降序排序,生成有序Map
        Map<Integer, List<Map<String, Object>>> sortedYearData = new LinkedHashMap<>();
        yearGroupedData.keySet().stream()
            .sorted(Comparator.reverseOrder())
            .forEach(year -> sortedYearData.put(year, yearGroupedData.get(year)));

        // 组装根节点primeData
        Map<String, Object> result = new HashMap<>();
        result.put("primeData", sortedYearData);
        return result;
    }
}

4. Controller返回结果

@RestController
@RequestMapping("/stats")
public class DataStatsController {
    @Autowired
    private DataStatsService statsService;

    @GetMapping("/grouped")
    public ResponseEntity<Map<String, Object>> getGroupedStats() {
        return ResponseEntity.ok(statsService.getPrimeData());
    }
}

最终返回JSON示例

{
  "primeData": {
    2024: [
      {"name": "A", "count": 15},
      {"name": "B", "count": 8}
    ],
    2023: [
      {"name": "A", "count": 12},
      {"name": "C", "count": 5}
    ]
  }
}

关键说明

  • DTO直接绑定统计结果,避免count被序列化为字符串
  • 通过流式API分组并排序年份,保证输出顺序符合要求
  • 最终结构以primeData为根节点,完全匹配需求格式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:55:18