当前位置: 首页 > news >正文

JPA 分页查询与条件分页查询

提示:前提是你的 orm 层使用的是 jpa,mybatis 的兄弟可以跳过,jdk 是17.

文章目录

  • 前言
  • 一、如何分页?
  • 二、如何携带过滤条件去分页?
  • 总结


前言

文章更多的是对我之前一篇文章的补充,springboot 集成 jpa,这篇文章大致说了如何集成以及如何快速的 CRUD,但是关于分页漏掉了,这里做补充。


提示:以下是本篇文章正文内容,下面案例可供参考

一、如何分页?

这里我先贴代码,方便急需使用的同学。

实体(数据库需要创建对应的 table):

import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;@Getter
@Setter
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "user")
public class User {@Id@Column(length = 32)private String id;private String name;private Integer age;private Double money;}

controller 层:

import com.demo.domain.PageR;
import com.demo.domain.R;
import com.demo.entity.User;
import com.demo.repository.UserRepository;
import jakarta.annotation.Resource;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/test")
public class TestController {@Resourceprivate UserRepository userRepository;@GetMapping("/page")public PageR<List<User>> findByPage(@RequestParam("pageNumber") Integer pageNumber,@RequestParam("pageSize") Integer pageSize) {// 因为底层的分页数是从0开始,所以需要将前端传递的参数减1,如果需要排序以及顺序还是倒序,可以参考我注释的部分,注释的部分是根据 name 字段倒叙。//Pageable pageable = PageRequest.of(pageNumber - 1, pageSize, Sort.by(Sort.Direction.DESC, "name"));Pageable pageable = PageRequest.of(pageNumber - 1, pageSize, Sort.unsorted());return R.pageOf(userRepository.findAll(pageable));}
}

持久层:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;@NoRepositoryBean
public interface AbstractRepository<T, K> extends JpaRepository<T, K>, JpaSpecificationExecutor<T> {
}
import com.repository.AbstractRepository;
import com.demo.entity.User;
import jakarta.persistence.criteria.Predicate;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Repository;import java.util.ArrayList;
import java.util.List;@Repository
public interface UserRepository extends AbstractRepository<User, String> {default Page<User> findAll(Pageable pageable) {Specification<User> spec = (root, query, criteriaBuilder) -> {List<Predicate> predicates = new ArrayList<>();return criteriaBuilder.and(predicates.toArray(new Predicate[0]));};return this.findAll(spec, pageable);}
}

到这里代码部分就已经完成了分页和排序,至于我 controller 层注释说的分页开始页,也可以让前端做个减 1 的操作,这样后端就不用处理;排序字段以及顺序还是倒序前端都可以传,后端做个默认处理都行,我一般都是用 createTime 做倒序排序,这个看需求。

二、如何携带过滤条件去分页?

这里我列举几个简单的场景供大家抄作业,后期关于其他条件过滤我会慢慢补充:

import com.repository.AbstractRepository;
import com.demo.entity.User;
import jakarta.persistence.criteria.Predicate;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Repository;import java.util.ArrayList;
import java.util.List;@Repository
public interface UserRepository extends AbstractRepository<User, String> {default Page<User> findAll(Integer age, String name, Date startDate, Date endDate, Pageable pageable) {Specification<User> spec = (root, query, criteriaBuilder) -> {List<Predicate> predicates = new ArrayList<>();// 精确匹配if (age != null) {predicates.add(criteriaBuilder.equal(root.get("age"), age));}// 模糊匹配if (name != null && !name.isEmpty()) {predicates.add(criteriaBuilder.like(root.get("name"), "%" + name + "%"));}// 范围匹配if (startDate != null && endDate != null) {predicates.add(criteriaBuilder.between(root.get("date"), startDate, endDate));} else {if (startDate != null) {predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("date"), startDate));}if (endDate != null) {predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("date"), endDate));}}return criteriaBuilder.and(predicates.toArray(new Predicate[0]));};return this.findAll(spec, pageable);}
}

这里大家不难发现我的参数都做了空判断,因为参数不可控,参数的判空是非常有必要的,这里的 date 字段是 user 实体中没有的,大家测试前需要自己加上去哈…


总结

基本以上代码能满足大家日常的开发了,至于如果大家遇到了第二部分没有的过滤,其实可以问问 ai,或者留言,我都会看的

——文章结束,2025.08.07

文章随手而作,其中错误跟漏洞难免,望海涵,如果大家觉的还行,不要吝啬点赞收藏,谢谢啦 ~~~~~~~~~~~

http://www.lryc.cn/news/612903.html

相关文章:

  • 《深入理解 WSGI:解锁 Python Web 应用背后的奥秘》
  • Java+Vue合力开发固定资产条码管理系统,移动端+后台管理,集成资产录入、条码打印、实时盘点等功能,助力高效管理,附全量源码
  • 前端性能优化:从请求到资源的精细调控
  • Event Stream输出优化:Vue3节流函数的正确实现
  • 【大前端】vite忽略指定前缀的静态资源
  • 【插件式微服务架构系统分享】之 解耦至上:gateway 网关与APISIX 网关的不同分工
  • 一文解读“Performance面板”前端性能优化工具基础用法!
  • SpringAI
  • 数据结构---循环队列(补充 应用实例)、哈希表(哈希存储、哈希冲突、解决方法、举例实现)
  • Linux Docker 新手入门:一文学会配置镜像加速器
  • 躺平发育小游戏微信抖音流量主小程序开源
  • 透明矿山:科技重塑矿业未来
  • Numpy科学计算与数据分析:Numpy随机数生成入门
  • 光纤滑环 – 光纤旋转接头(FORJ)- 杭州驰宏科技
  • AutoMQ-Kafka的替代方案实战
  • QML与C++交互的方式
  • Kafka数据生产和发送
  • 基于Spring Cloud Stream与Kafka的事件驱动微服务架构设计与实战指南
  • 【Kafka系列】第二篇| Kafka 的核心概念、架构设计、底层原理
  • MQTT:Dashboard访问授权
  • MQTT:Dashboard黑名单与连接抖动
  • 【LeetCode】set和map相关算法题 前K个高频单词、随机链表的复制、两个数组的交集、环形链表
  • Flink-1.19.0源码详解9-ExecutionGraph生成-后篇
  • VScode使用jupyter notebook,配置内核报错没有torch解决
  • 贪心算法分析与解决指南
  • 1.电动汽车动力电池系统技术介绍与分类
  • 机器视觉系统工业相机的成像原理及如何选型
  • OpenCV图像处理入门实战指南
  • 为什么需要日志收集系统
  • 【运维】自动化生产环境部署工作流