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

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代码转换

如果后续需要对数据做额外的业务加工,用代码转换灵活性更高,实现步骤如下:

  1. 定义原始数据映射实体和响应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;
    }
}
  1. 业务层转换逻辑
@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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:12:03