PreparedStatement不支持参数双向绑定,仅单向设置SQL参数;分页元数据需业务层通过额外查询(如COUNT(*))或窗口函数组装返回。

Java 中 PreparedStatement 本身不直接支持“参数双向绑定”,它只负责将 Java 变量单向设置(setXXX)到 SQL 的占位符中。所谓“分页查询参数双向绑定”,实际是指:在执行分页查询时,既把页码、每页大小等参数传入 SQL(如 LIMIT ?, ?),又在查询结果返回后,将分页元信息(如总记录数、当前页、总页数等)一并封装返回给调用方——这属于业务层的数据组装,不是 PreparedStatement 的能力范围。
分页查询的典型 SQL 结构(以 MySQL 为例)
标准分页需两个关键参数:起始偏移量(offset) 和 每页数量(limit)。例如:
SELECT * FROM user WHERE status = ? ORDER BY id LIMIT ?, ?
对应三个参数:状态值、offset、limit。其中 offset = (pageNum - 1) * pageSize。
用 PreparedStatement 安全设置分页参数
避免字符串拼接,防止 SQL 注入。示例代码片段:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
String sql = "SELECT * FROM user WHERE status = ? ORDER BY id LIMIT ?, ?";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, status); // 条件参数
ps.setInt(2, (pageNum - 1) * pageSize); // offset
ps.setInt(3, pageSize); // limit
ResultSet rs = ps.executeQuery();
// 处理结果集...
}
如何“返回”分页元数据?(即所谓“双向”的后半部分)
PreparedStatement 不返回参数值,但你可以通过额外查询或一次查两条语句(推荐用 UNION 或子查询优化)获取总数。常见做法:
-
方式一:两次查询(清晰、兼容性强)
先查总数:SELECT COUNT(*) FROM user WHERE status = ?;再查分页数据。 -
方式二:单次查询封装(MySQL 8.0+ 支持窗口函数)
用COUNT(*) OVER()同时返回每行数据和总条数,例如:
SELECT *, COUNT(*) OVER() AS total FROM user WHERE status = ? ORDER BY id LIMIT ?, ? -
方式三:自定义分页对象封装
定义 PageResult类,包含 List data、int total、int pageNum、int pageSize 等字段,由 DAO/Service 层组装返回。
完整轻量示例(含总数 + 分页数据)
使用两次 PreparedStatement 查询(适合大多数场景):
public PageResult<user> findUsersByStatus(int status, int pageNum, int pageSize) {
String countSql = "SELECT COUNT(*) FROM user WHERE status = ?";
String dataSql = "SELECT * FROM user WHERE status = ? ORDER BY id LIMIT ?, ?";
<pre class="brush:php;toolbar:false;">int total = 0;
List<user> list = new ArrayList();
try (PreparedStatement psCount = conn.prepareStatement(countSql);
PreparedStatement psData = conn.prepareStatement(dataSql)) {
// 查总数
psCount.setInt(1, status);
try (ResultSet rsCount = psCount.executeQuery()) {
if (rsCount.next()) total = rsCount.getInt(1);
}
// 查分页数据
psData.setInt(1, status);
psData.setInt(2, (pageNum - 1) * pageSize);
psData.setInt(3, pageSize);
try (ResultSet rsData = psData.executeQuery()) {
while (rsData.next()) {
list.add(new User(rsData.getInt("id"), rsData.getString("name")));
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return new PageResult(list, total, pageNum, pageSize);</user>
}
不复杂但容易忽略:offset 计算要防负数(pageNum ≤ 0 时应校验)、pageSize 建议设上限(如 ≤ 100),避免恶意拖库。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










