PreparedStatement 实现分页查询详解

PreparedStatement 实现分页查询详解

在 JDBC 中使用 PreparedStatement 实现分页查询是高效安全的方式,可以避免 SQL 注入并提升性能。下面我将详细说明实现步骤和原理。

📐 分页查询核心参数

参数名说明计算公式
pageNum当前页码(从1开始)用户输入
pageSize每页显示的记录数用户输入或系统默认值
offset数据偏移量(跳过的记录数)(pageNum - 1) * pageSize
limit每页获取的记录数等于 pageSize

📝 分页查询实现步骤

1. 构建分页SQL语句(以MySQL为例)

SELECT * FROM your_table 
ORDER BY sort_column 
LIMIT ? OFFSET ?
  • LIMIT: 指定每页返回的记录数
  • OFFSET: 指定跳过的记录数
  • ORDER BY: 必须指定排序字段,确保分页结果稳定

2. Java 实现代码

public List<YourEntity> getPagedData(int pageNum, int pageSize) {List<YourEntity> resultList = new ArrayList<>();String sql = "SELECT id, name, email FROM users ORDER BY id LIMIT ? OFFSET ?";// 计算偏移量int offset = (pageNum - 1) * pageSize;try (Connection conn = dataSource.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) {// 设置参数pstmt.setInt(1, pageSize);   // LIMIT 参数pstmt.setInt(2, offset);     // OFFSET 参数try (ResultSet rs = pstmt.executeQuery()) {while (rs.next()) {YourEntity entity = new YourEntity();entity.setId(rs.getLong("id"));entity.setName(rs.getString("name"));entity.setEmail(rs.getString("email"));resultList.add(entity);}}} catch (SQLException e) {throw new DataAccessException("分页查询失败", e);}return resultList;
}

3. 不同数据库的分页语法差异

数据库分页语法示例备注
MySQLLIMIT ? OFFSET ?最常用
PostgreSQLLIMIT ? OFFSET ?同 MySQL
OracleOFFSET ? ROWS FETCH NEXT ? ROWS ONLY12c 及以上版本
SQL ServerOFFSET ? ROWS FETCH NEXT ? ROWS ONLY2012 及以上版本
SQLiteLIMIT ? OFFSET ?同 MySQL

Oracle 兼容写法 (旧版本):

SELECT * FROM (SELECT t.*, ROWNUM rn FROM (SELECT * FROM your_table ORDER BY sort_column) t WHERE ROWNUM <= ?
) WHERE rn > ?

🔍 分页查询最佳实践

1. 获取总记录数

public int getTotalRecords() {String countSql = "SELECT COUNT(*) FROM your_table";try (Connection conn = dataSource.getConnection();PreparedStatement pstmt = conn.prepareStatement(countSql);ResultSet rs = pstmt.executeQuery()) {if (rs.next()) {return rs.getInt(1);}} catch (SQLException e) {// 异常处理}return 0;
}

2. 计算总页数

int totalRecords = getTotalRecords();
int totalPages = (int) Math.ceil((double) totalRecords / pageSize);

3. 分页参数校验

// 确保页码有效
pageNum = Math.max(1, pageNum); // 限制每页最大记录数
pageSize = Math.min(100, Math.max(1, pageSize));

⚠️ 分页查询注意事项

  1. 必须排序:分页查询必须指定 ORDER BY 子句,否则结果顺序不确定
  2. 性能优化
    • 在排序字段上创建索引
    • 避免 SELECT *,只查询必要字段
    • 大数据量表考虑使用基于键的分页(WHERE id > ?)
  3. 连接池使用:确保使用数据库连接池(如 HikariCP)
  4. 事务管理:在同一个事务中获取数据和总记录数,保证一致性
  5. 参数绑定:务必使用 PreparedStatement 防止 SQL 注入

🌟 高级分页技术

1. 键集分页(Keyset Pagination)

适用于超大数据集,性能优于传统分页

SELECT * FROM your_table 
WHERE id > ? 
ORDER BY id 
LIMIT ?

2. 前端分页参数处理

// 前端请求示例
const pageRequest = {page: 2,size: 10,sort: "name,asc|email,desc"
};

3. Spring Data JPA 分页

Pageable pageable = PageRequest.of(pageNum - 1, pageSize, Sort.by("name"));
Page<User> page = userRepository.findAll(pageable);List<User> users = page.getContent();
long totalItems = page.getTotalElements();
int totalPages = page.getTotalPages();

💡 总结

使用 PreparedStatement 实现分页查询的关键点:

  1. 正确计算 OFFSETLIMIT
  2. 根据数据库类型使用正确的分页语法
  3. 必须指定 ORDER BY 子句
  4. 结合总记录数计算实现完整的分页功能
  5. 使用参数绑定防止 SQL 注入
开始分页查询
计算偏移量 offset
构建分页SQL
创建PreparedStatement
设置LIMIT参数
设置OFFSET参数
执行查询
处理结果集
获取总记录数
计算总页数
返回分页结果

在实际项目中,推荐使用成熟的 ORM 框架(如 MyBatis、Hibernate)的分页功能,它们已经处理了各种数据库的兼容性问题,并提供了更简洁的 API。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/88434.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/88434.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ClamAV 和 FreshClam:Linux 服务器上的开源杀毒解决方案

ClamAV 和 FreshClam:Linux 服务器上的开源杀毒解决方案 1. 概述 ClamAV 是一款开源的防病毒引擎,专为 Linux 服务器设计,用于检测恶意软件、病毒、木马和其他安全威胁。它广泛应用于邮件服务器、文件存储系统和 Web 服务器,提供高效的病毒扫描功能。 主要特点: 免费开…

PySpark中python环境打包和JAR包依赖

在 PySpark 中打包 Python 环境并调度到集群是处理依赖一致性的关键步骤。以下是完整的解决方案&#xff0c;包含环境打包、分发和配置方法&#xff1a; 一、环境打包方法 使用 Conda 打包环境 # 创建 Conda 环境 conda create -n pyspark_env python3.8 conda activate pyspar…

和鲸社区深度学习基础训练营2025年关卡2(1)纯numpy

拟分3种实现方法&#xff1a;1.纯numpy2.sklearn中的MLPClassifier3.pytorch题目&#xff1a; 在 MNIST 数据集上训练 MLP 模型并比较不同的激活函数和优化算法任务描述&#xff1a;使用 MNIST 数据集中的前 20,000 个样本训练一个多层感知机 (MLP) 模型。你需要比较三种不同的…

Sequential Thinking:AI深度思考的新范式及其与CoT、ReAct的对比分析

引言&#xff1a;AI深度思考的演进与Sequential Thinking的崛起在人工智能技术快速发展的今天&#xff0c;AI模型的思考能力正经历着从简单应答到深度推理的革命性转变。这一演进过程不仅反映了技术本身的进步&#xff0c;更体现了人类对机器智能认知边界的持续探索。早期的大语…

云原生详解:构建现代化应用的未来

引言 在数字化转型的浪潮中,"云原生"已成为技术领域最热门的话题之一。从初创公司到全球500强企业,都在积极探索云原生技术以提升业务敏捷性和创新能力。本文将全面解析云原生的概念、核心技术、优势以及实践路径,帮助您深入理解这一改变IT格局的技术范式。 什么…

SSE事件流简单示例

文章目录1、推送-SseEmitter2、接收-EventSourceListenerSSE&#xff08;Server-Sent Events&#xff0c;服务器推送事件&#xff09;是一种基于HTTP的服务器向客户端实时推送数据的技术标准。1、推送-SseEmitter SseEmitter用于实现服务器向客户端单向、长连接的实时数据推送…

Elasticsearch RESTful API入门:基础搜索与查询DSL

Elasticsearch RESTful API入门&#xff1a;基础搜索与查询DSL 本文为Elasticsearch初学者详细解析RESTful API的核心操作与查询DSL语法&#xff0c;包含大量实战示例及最佳实践。 一、Elasticsearch与RESTful API简介 Elasticsearch&#xff08;ES&#xff09;作为分布式搜索…

(六)复习(OutBox Message)

文章目录 项目地址一、OutBox Message1.1 OutBox表配置1. OutBoxMessage类2. OutboxMessage表配置3. 给每个模块生成outboxmessage表1.2 发布OutBox Message1. 修改Intercepotor2. 配置Quartz3. 创建Quatz方法发布领域事件4. 创建Quatz定时任务5. 注册Quatz服务和配置6. 流程梳…

STM32-ADC内部温度

在通道16无引脚&#xff08;测量温度不准确&#xff09;跟ADC代码差不多&#xff1b;不需要使能引脚时钟&#xff1b;将内部温度测量打开/*** brief 启用或禁用温度传感器和内部参考电压功能* param NewState: 新的功能状态&#xff0c;取值为ENABLE或DISABLE* retval 无* no…

「Linux命令基础」文本模式系统关闭与重启

关机重启基本命令 直接拔掉计算机电源可能损坏内部元件;Linux系统通过命令关闭计算机则是安全流程,让所有程序有机会保存数据、释放资源。 关机命令:shutdown Linux系统提供了多种用于关闭或重启系统的命令,其中 shutdown 是最常用的一种,它可以安全地通知用户系统即将…

射频信号(大宽高比)时频图目标检测anchors配置

一、大宽高比目标YOLO检测参数设置 这是yolov7的一个label的txt文件&#xff1a; 1 0.500 0.201 1.000 0.091 2 0.500 0.402 1.000 0.150 3 0.500 0.604 1.000 0.093 0 0.500 0.804 1.000 0.217 对应的样本&#xff1a; 长宽比分别是&#xff1a;1/0.09110.98, 1/0.1506.67…

OpenStack 鉴权服务介绍.md

引言 OpenStack是一个开源的云计算管理平台&#xff0c;其中的Keystone组件承担了身份认证和授权的关键任务。Keystone的主要功能包括管理用户及其权限、维护OpenStack Services的Endpoint&#xff0c;以及实现认证&#xff08;Authentication&#xff09;和鉴权&#xff08;Au…

Linux_3:进程间通信

IPC1.什么是IPC&#xff1f;Inter Process Communication2.进程间通信常用的几种方式1&#xff0c;管道通信&#xff1a;有名管道&#xff0c;无名管道2&#xff0c;信号- 系统开销小3&#xff0c;消息队列-内核的链表4&#xff0c;信号量-计数器5&#xff0c;共享内存6&#x…

【Springboot】Bean解释

在 Spring Boot 中&#xff0c;Bean 就像是你餐厅里的一名员工。比如&#xff0c;你有一名服务员&#xff08;Service&#xff09;、一名厨师&#xff08;Chef&#xff09;和一名收银员&#xff08;Cashier&#xff09;。这些员工都是餐厅正常运转所必需的&#xff0c;他们各自…

axios的post请求,数据为什么要用qs处理?什么时候不用?

为什么使用 qs 处理 POST 数据axios 的 POST 请求默认将 JavaScript 对象序列化为 JSON 格式&#xff08;Content-Type: application/json&#xff09;。但某些后端接口&#xff08;尤其是传统表单提交&#xff09;要求数据以 application/x-www-form-urlencoded 格式传输&…

【unitrix】 4.21 类型级二进制数基本结构体(types.rs)

一、源码 这段代码定义了一个类型级数值系统的 Rust 实现&#xff0c;主要用于在编译时表示和操作各种数值类型。 use crate::sealed::Sealed; use crate::number::{NonZero, TypedInt, Unsigned, Primitive}; // // 特殊浮点值枚举 ///// 特殊浮点值&#xff08;NaN/∞&#x…

UI前端与数字孪生结合实践案例:智慧零售的库存管理优化系统

hello宝子们...我们是艾斯视觉擅长ui设计和前端数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩!一、引言&#xff1a;数字孪生重构零售库存的 “人 - 货 - 场” 协同在零售行业利润率持续承压的背景…

【Freertos实战】零基础制作基于stm32的物联网温湿度检测(教程非常简易)持续更新中.........

本次记录采用Freertos的第二个DIY作品&#xff0c;基于Onenet的物联网温湿度检测系统&#xff0c;此次代码依然是全部开源。通过网盘分享的文件&#xff1a;物联网温湿度检测.rar 链接: https://pan.baidu.com/s/1uj9UURVtGE6ZB6OsL2W8lw?pwdqm2e 提取码: qm2e 大家也可以看看…

Matplotlib-多图布局与网格显示

Matplotlib-多图布局与网格显示一、多图布局的核心组件二、基础布局&#xff1a;plt.subplots()快速创建网格1. 均等分网格2. 不等分网格&#xff08;指定比例&#xff09;三、进阶布局&#xff1a;GridSpec实现复杂嵌套1. 跨行列布局2. 嵌套GridSpec四、实用技巧&#xff1a;布…

GitHub上优秀的开源播放器项目介绍及优劣对比

ExoPlayer 项目地址:https://github.com/google/ExoPlayer 特点: 由Google开发,支持广泛的视频格式和流媒体传输协议,如DASH、HLS、SmoothStreaming。 提供灵活的媒体源架构和高级特性,如动态自适应流播放。 开发者可以轻松扩展和定制播放器组件,适应特定需求。 优点: 功…