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
相关产品推荐
相关产品推荐

