【Java Web】分页查询

分页查询

分页查询用于在处理大量数据时,将数据分成多个小部分(页)来展示。这样可以提高用户体验,减少单次加载的数据量,从而加快页面响应速度,并且降低服务器和数据库的负载。

基本概念

  • 页大小(Page Size):每一页显示的记录数量。
  • 当前页码(Current Page Number):用户正在查看的页码。
  • 总记录数(Total Record Count):数据库中满足条件的总记录数。
  • 总页数(Total Pages):基于总记录数和页大小计算得出的总页数。
  • 偏移量(Offset):从第一条记录开始到当前页的第一条记录之间的距离。
java 复制代码
// 总记录数除以页大小(向上取整)得到总页数
int totalPages = (int) Math.ceil((double) totalRecords / pageSize);

基本步骤

升级示例5

在 DAO 层,获取总记录数,根据传入的偏移量(offset)和每页显示记录数(pageSize)来构建SQL查询语句。

java 复制代码
// 修改公共接口全查方法,加入参数
public interface PublicInterface<E> {
    /**
     * 分页全查
     * @param offset 偏移量
     * @param pageSize 每页显示记录数
     * @return
     */
    List<E> findAll(Integer offset, Integer pageSize);
    /**
     * 获取总记录数
     * @return int
     */
    int findListCount();
}
java 复制代码
// 添加 limit 条件
@Override
public List<SmbmsProvider> findAll(Integer offset, Integer pageSize) {
    ...
    String sql = "select id,proCode,proName,proDesc,creationDate " +
        "from smbms_provider order by creationDate desc limit ?,?";
    ResultSet res = query(sql,offset,pageSize);
    ...
}
@Override
public int findListCount() {
    try {
        int count = 0;
        if (getConnection()) {
            String sql = "select count(1) count from smbms_provider";
            ResultSet res =  query(sql,null);
            while(res.next()){
                count = res.getInt("count");
            }
        }
        return count;
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        closeResources(); // 释放资源
    }
    return 0;
}

在 Service 层,处理业务逻辑,包括根据当前页(pageNow)计算偏移量(offset)、根据总记录数(count)计算总页数(pageCount)。

java 复制代码
public interface SmbmsProviderService {
    /**
     * 分页全查
     * @param pageNow 当前页
     * @param pageSize 每页显示记录数
     * @return
     */
    public List<SmbmsProvider> findAll(Integer pageNow, Integer pageSize);

    /**
     * 获得总页数
     * @return int
     */
    public int findListCount(Integer pageSize);
}
java 复制代码
@Override
public List<SmbmsProvider> findAll(Integer pageNow, Integer pageSize) {
    int offset = (pageNow - 1) * pageSize;
    return smbmsProviderDao.findAll(offset, pageSize);
}

@Override
public int findListCount(Integer pageSize) {
    // 获取总记录数
    int count = smbmsProviderDao.findListCount();
    // 总页数 = 总记录数%每页显count示记录数==0?(总记录数/每页显示记录数):(总记录数/每页显示记录数)+1
    int pageCount = count % pageSize == 0 ? (count / pageSize) : (count / pageSize) + 1;
    return pageCount;
}

在 Servlet 中,接收前端请求参数获取当前页码,调用 Service 层的方法获取总页数(pageCount),处理当前页(pageNow),最后将这些信息设置到请求属性中转发给视图。

java 复制代码
int pageCount; // 总页数
int pageSize = 5;  // 每页显示记录数
// 从请求参数中获取当前页码
int pageNow = 1;
if (request.getParameter("page") != null) {
    pageNow = Integer.parseInt(request.getParameter("page"));
}
// 调用 Java 方法 获取供应商列表信息
List<SmbmsProvider> providerList = smbmsProviderService.findAll(pageNow,pageSize);
// 获得总页数
pageCount = smbmsProviderService.findListCount(pageSize);

// 将数据和分页信息放入请求属性
request.setAttribute("providerList", providerList);
request.setAttribute("pageNow", pageNow);
request.setAttribute("pageCount", pageCount);

index.jsp 实现分页导航的功能

jsp 复制代码
<div class="pagination">
    <a <c:if test="${pageNow == 1}">class="disabled"</c:if> <c:if test="${pageNow > 1}">href="/index?page=1"</c:if>>首页</a>
    <a <c:if test="${pageNow == 1}">class="disabled"</c:if> <c:if test="${pageNow > 1}">href="/index?page=${pageNow - 1}"</c:if>>上一页</a>

    <c:forEach begin="1" end="${pageCount}" var="i">
        <c:choose>
            <c:when test="${i == pageNow}">
                <a class="active">${i}</a>
            </c:when>
            <c:otherwise>
                <a href="/index?page=${i}">${i}</a>
            </c:otherwise>
        </c:choose>
    </c:forEach>

    <a <c:if test="${pageNow == pageCount}">class="disabled"</c:if> <c:if test="${pageNow < pageCount}">href="/index?page=${pageNow + 1}"</c:if>>下一页</a>
    <a <c:if test="${pageNow == pageCount}">class="disabled"</c:if> <c:if test="${pageNow < pageCount}">href="/index?page=${pageCount}"</c:if>>尾页</a>
    当前第 ${pageNow} / ${pageCount} 页
</div>
相关推荐
evans在进步1 分钟前
Spring Boot 核心机制详解:自动装配、事件监听、异步任务与请求映射
java·spring boot·后端
码云骑士6 分钟前
116-Python调用GPT-4V分析图片-Base64编码-多图-JSON结构化输出
开发语言·python·json
Zane19946 分钟前
HashSet、TreeSet、LinkedHashSet:底层都是"套壳"
java·后端
88号技师13 分钟前
2026年SCI-分数牛顿衍生优化算法Fractional Newton-derived optimizer-附Matlab免费代码
开发语言·算法·数学建模·matlab·优化算法
承渊政道13 分钟前
【Python编程—从入门到实践】(Python操作列表深度教程:循环、切片、元组与代码风格)
开发语言·python·pycharm·列表·元组·切片
相顾若初见20 分钟前
RuoYi后端jar镜像制作
java·jar
布值倒区什么name22 分钟前
Pycharm2026找不到编译器 点击运行运行不了
开发语言·python·pycharm
MacroZheng27 分钟前
程序员看文档神器,装上它,看Spring官方文档就一目了然了!
java·人工智能·后端
智购科技自动售货机工厂29 分钟前
2026自动售货机电机驱动芯片选型:从L298N到DRV8870的工程实践~YH
大数据·开发语言·数据库·人工智能·单片机·嵌入式硬件·scikit-learn
2501_9159184135 分钟前
Rust 程序抓包解密,rustls 不认系统证书的几种办法
开发语言·后端·网络协议·ios·adb·https·rust