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

Spring Boot中使用Pageable构造含嵌套列表的ResponseDto的高效方案问询

优化方案

你当前的实现存在典型的N+1查询问题:每次遍历Page元素都会单独发起一次数据库请求,总查询次数为1(查主Page)+ N(Page元素个数),数据量较大时性能损耗非常严重,可通过批量查询+内存匹配的方式将查询次数降到固定2次,大幅提升效率

具体实现步骤

  • 第一步:查询得到主数据Page<ResponseDto>
  • 第二步:提取Page中所有ResponseDto的关联字段someProp值,去重后得到批量查询的参数集合
  • 第三步:调用批量查询接口一次性拿到所有关联的NestedDto,组装为key为someProp值、value为对应NestedDto列表的映射Map
  • 第四步:遍历Page中的ResponseDto元素,直接从Map中取出对应嵌套列表赋值,纯内存操作无额外IO开销

代码示例

// 1. 查询主记录分页数据
Page<ResponseDto> responsePage = repository.findRecord();

// 2. 提取所有关联键,去重减少无效查询
List<String> somePropList = responsePage.getContent().stream()
        .map(ResponseDto::getSomeProp)
        .distinct()
        .toList();

// 3. 批量查询所有嵌套数据,组装为映射Map
// 需先在otherRepository中新增批量查询方法
Map<String, List<NestedDto>> nestedDtoMap = otherRepository.findNestedRecordBySomePropIn(somePropList)
        .stream()
        .collect(Collectors.groupingBy(NestedDto::getSomeProp));

// 4. 内存赋值,无数据库请求
for (ResponseDto dto : responsePage.getContent()) {
    dto.setNestedDto(nestedDtoMap.getOrDefault(dto.getSomeProp(), Collections.emptyList()));
}

补充说明

需要先在otherRepository中新增批量查询方法,若使用Spring Data JPA,按命名规则定义即可,无需手动编写SQL,方法签名参考:

List<NestedDto> findNestedRecordBySomePropIn(List<String> somePropList);

如果你的业务场景允许主表和嵌套表做关联查询,也可以直接在主查询中通过关联查询一次性封装好嵌套字段,只需要1次数据库查询,性能更高。但如果两个表属于不同数据源、或者关联查询性能不如两次单表查询的场景,优先使用上述批量查询方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:54:04