java中jdbc分页查询需借助数据库原生语法(如mysql的limit、oracle的offset...fetch),通过pageno和pagesize计算offset=(pageno-1)*pagesize,避免全量加载;注意深度分页性能问题,并按数据库类型适配sql语法。

Java 中用 JDBC 实现分页查询,核心是借助数据库自身的分页语法(如 MySQL 的 LIMIT offset, size、PostgreSQL 的 LIMIT size OFFSET offset、Oracle 的 ROWNUM 或 OFFSET ... FETCH),在 SQL 层控制返回的数据范围,而不是把全量数据查出来再在 Java 里截取——后者在大数据量下会严重浪费内存和网络资源。
明确分页参数含义
分页通常需要两个关键参数:
- pageNo:当前页码(一般从 1 开始)
- pageSize:每页记录数
由此可算出起始位置:offset = (pageNo - 1) * pageSize。注意:SQL 中的 offset 通常从 0 开始计数。
MySQL 示例:使用 LIMIT + OFFSET
这是最直观的方式:
String sql = "SELECT id, name, age FROM user ORDER BY id LIMIT ?, ?"; PreparedStatement ps = connection.prepareStatement(sql); ps.setInt(1, (pageNo - 1) * pageSize); // offset ps.setInt(2, pageSize); // limit ResultSet rs = ps.executeQuery();
✅ 优点:简洁高效,适合中小数据量;
⚠️ 注意:深度分页(如 LIMIT 1000000, 20)性能会下降,因 MySQL 仍需扫描前 100 万行。
通用性增强:适配不同数据库
如果项目可能切换数据库,建议封装分页 SQL 构建逻辑:
- MySQL / PostgreSQL / HSQLDB:用
LIMIT ? OFFSET ?(PostgreSQL 语法)或LIMIT ?, ?(MySQL) - Oracle 12c+:用
OFFSET ? ROWS FETCH NEXT ? ROWS ONLY - SQL Server:用
OFFSET ? ROWS FETCH NEXT ? ROWS ONLY - 旧版 Oracle(ROWNUM 查询,较复杂,不推荐直接手写
实际开发中,更推荐用 MyBatis、JPA 等框架自动处理多数据库分页,或统一使用标准 JPA 的 Pageable 接口。
补充:获取总记录数(用于计算总页数)
分页常需显示“共 N 条,第 X 页/共 Y 页”,所以要额外查一次总数:
String countSql = "SELECT COUNT(*) FROM user WHERE status = ?"; PreparedStatement countPs = connection.prepareStatement(countSql); countPs.setInt(1, 1); long total = ((Long) countPs.executeQuery().getLong(1)); int totalPages = (int) Math.ceil((double) total / pageSize);
⚠️ 建议将 count 查询和分页查询放在同一事务中(尤其涉及动态条件时),避免数据不一致;也可考虑用缓存或近似值优化高频 count 场景。
不复杂但容易忽略的是:参数校验(如 pageNo ≤ 0、pageSize 超大)、SQL 注入防护(务必用 PreparedStatement)、以及空结果集的健壮处理。真正上线前,记得压测深度分页场景。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











