Java Spring Boot中如何将PostgreSQL查询结果转换为指定嵌套JSON结构
解决方案
两种方式都可以实现需求,你可以根据自己的业务场景选择:
方案1:直接通过PostgreSQL SQL查询聚合
PostgreSQL内置了JSON相关的聚合函数,不需要写Java代码就可以直接返回符合要求的结构:
-- 按offerId、warehouseId分组,聚合生成types数组 SELECT offerId, warehouseId, json_agg( json_build_object( 'type', type, 'quantity', quantity ) ) AS types FROM 你的表名 GROUP BY offerId, warehouseId;
如果你需要直接返回完整的JSON对象,可以再加一层封装:
SELECT json_build_object( 'offerId', offerId, 'warehouseId', warehouseId, 'types', json_agg(json_build_object('type', type, 'quantity', quantity)) ) AS response_json FROM 你的表名 GROUP BY offerId, warehouseId;
方案2:通过Java Spring Boot代码转换
如果后续需要对数据做额外的业务加工,用代码转换灵活性更高,实现步骤如下:
- 定义原始数据映射实体和响应DTO
// 数据库原始表映射实体 @Data @Table(name = "你的表名") @Entity public class OfferInventory { private Long offerId; private Long warehouseId; private String type; private Integer quantity; }
// 接口响应DTO @Data public class OfferInventoryResp { private Long offerId; private Long warehouseId; private List<TypeQuantity> types; @Data public static class TypeQuantity { private String type; private Integer quantity; } }
- 业务层转换逻辑
@Service public class OfferInventoryService { @Autowired private OfferInventoryRepository offerInventoryRepository; public List<OfferInventoryResp> getAggregatedData() { // 先查询所有原始数据 List<OfferInventory> rawData = offerInventoryRepository.findAll(); // 按offerId+warehouseId分组 Map<List<Long>, List<OfferInventory>> groupMap = rawData.stream() .collect(Collectors.groupingBy(item -> Arrays.asList(item.getOfferId(), item.getWarehouseId()))); // 转换为目标响应格式 return groupMap.entrySet().stream() .map(entry -> { OfferInventoryResp resp = new OfferInventoryResp(); resp.setOfferId(entry.getKey().get(0)); resp.setWarehouseId(entry.getKey().get(1)); List<OfferInventoryResp.TypeQuantity> typeList = entry.getValue().stream() .map(raw -> { OfferInventoryResp.TypeQuantity tq = new OfferInventoryResp.TypeQuantity(); tq.setType(raw.getType()); tq.setQuantity(raw.getQuantity()); return tq; }).collect(Collectors.toList()); resp.setTypes(typeList); return resp; }).collect(Collectors.toList()); } }
方案选择建议
- 数据量不大、不需要额外业务处理的场景优先选SQL方案,代码量更少性能更高
- 后续需要对库存数据做额外计算、扩展其他业务字段的场景选Spring Boot代码转换方案,灵活性更高
内容的提问来源于stack exchange,提问作者cypher
相关产品推荐
相关产品推荐

