【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>
相关推荐
ac-er88882 分钟前
ThinkPHP中的MVC分层是什么
开发语言·php·mvc
惜.己4 分钟前
Jmeter中的配置原件(四)
java·前端·功能测试·jmeter·1024程序员节
yava_free28 分钟前
JVM这个工具的使用方法
java·jvm
shinelord明32 分钟前
【再谈设计模式】建造者模式~对象构建的指挥家
开发语言·数据结构·设计模式
黑不拉几的小白兔1 小时前
PTA部分题目C++重练
开发语言·c++·算法
写bug的小屁孩1 小时前
websocket身份验证
开发语言·网络·c++·qt·websocket·网络协议·qt6.3
不会编程的懒洋洋1 小时前
Spring Cloud Eureka 服务注册与发现
java·笔记·后端·学习·spring·spring cloud·eureka
赖龙1 小时前
java程序打包及执行 jar命令及运行jar文件
java·pycharm·jar
U12Euphoria1 小时前
java的runnable jar采用exe和.bat两种方式解决jre环境的问题
java·pycharm·jar
材料苦逼不会梦到计算机白富美1 小时前
线性DP 区间DP C++
开发语言·c++·动态规划