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

JPA自定义查询List转Page分页失效,修改page/size参数无响应如何解决?

问题根因

你当前的实现属于典型的假分页,核心问题出在Repository层的自定义查询逻辑:

  • 调用entityManager.createQuery(query.where(predicate)).getResultList()时,没有给查询应用分页参数,会把所有符合筛选条件的Car记录全部从数据库查出来,无论传入的page和size是什么值
  • 后续用全量列表封装PageImpl时,总条数直接传了当前全量列表的长度,就算Page对象里携带分页参数,返回的内容还是全量数据,因此分页参数修改不会生效
修复方案

第一步:修改Repository层自定义搜索逻辑

需要调整三处逻辑:先构建统一查询条件、再查询符合条件的总记录数、最后给查询应用分页+排序参数后查询当前页数据,修改后代码如下:

@Override
public Page<Car> search(Pageable pageable, String brand, String model, String type, Integer registrationYear, String color,
                        String fuel, String transmission, String doors, double price) {
    int var = 0;
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    // 1. 构建公共查询条件
    CriteriaQuery<Car> query = cb.createQuery(Car.class);
    Root<Car> car = query.from(Car.class);
    query.select(car);
    Predicate predicate = cb.greaterThan(car.get("id"), var);

    if (brand != null) predicate = cb.and(predicate, cb.equal(car.get("brand"), brand));
    if (model != null) predicate = cb.and(predicate, cb.equal(car.get("model"), model));
    if (type != null) predicate = cb.and(predicate, cb.equal(car.get("type"), type));
    if (registrationYear != null)
        predicate = cb.and(predicate, cb.equal(car.get("registrationNumber"), registrationYear));
    if (color != null) predicate = cb.and(predicate, cb.equal(car.get("color"), color));
    if (fuel != null) predicate = cb.and(predicate, cb.equal(car.get("fuel"), Fuel.stringToFuelEnum(fuel)));
    if (transmission != null)
        predicate = cb.and(predicate, cb.equal(car.get("transmission"), Transmission.stringToTransmissionEnum(transmission)));
    if (doors != null) predicate = cb.and(predicate, cb.equal(car.get("doors"), doors));
    if (price != 0) predicate = cb.and(predicate, cb.lessThan(car.get("price"), price));
    query.where(predicate);

    // 2. 新增:查询符合条件的总记录数,用于Page对象计算总页数
    CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
    Root<Car> countRoot = countQuery.from(Car.class);
    countQuery.select(cb.count(countRoot)).where(cb.and(predicate, cb.greaterThan(countRoot.get("id"), var)));
    Long total = entityManager.createQuery(countQuery).getSingleResult();

    // 3. 新增:给查询应用分页+排序参数,查询当前页对应的数据
    List<Car> carList = entityManager.createQuery(query)
            .setFirstResult((int) pageable.getOffset()) // 分页起始位置
            .setMaxResults(pageable.getPageSize()) // 每页最多返回条数
            .getResultList();

    // 4. 传入真实总条数封装正确的Page对象
    return new PageImpl<>(carList, pageable, total);
}

第二步(可选优化):简化Controller层参数

Spring Boot默认配置下Pageable会自动解析请求中的page、size、sort参数,不需要手动重复声明page和size参数,简化后代码如下:

@GetMapping("/find")
ResponseEntity<Page<CarDTO>> readAllCarsFiltered(@PageableDefault(page = 0, size = 5) Pageable pageable,
                                                 @RequestParam(required = false) String brand,
                                                 @RequestParam(required = false) String model,
                                                 @RequestParam(required = false) String type,
                                                 @RequestParam(required = false) Integer registrationYear,
                                                 @RequestParam(required = false) String color,
                                                 @RequestParam(required = false) String fuel,
                                                 @RequestParam(required = false) String transmission,
                                                 @RequestParam(required = false) String doors,
                                                 @RequestParam(required = false, defaultValue = "9999999999") double price) {
    return ResponseEntity.ok(carService.customerSearch(pageable,
            brand, model, type, registrationYear, color, fuel, transmission, doors, price));
}

通过@PageableDefault注解可以直接配置默认分页参数,无需单独声明page和size的默认值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:54:08