分页查询

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

基本概念

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

基本步骤

升级示例5

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

// 修改公共接口全查方法,加入参数
public interface PublicInterface<E> {
    /**
     * 分页全查
     * @param offset 偏移量
     * @param pageSize 每页显示记录数
     * @return
     */
    List<E> findAll(Integer offset, Integer pageSize);
    /**
     * 获取总记录数
     * @return int
     */
    int findListCount();
}
// 添加 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)。

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

    /**
     * 获得总页数
     * @return int
     */
    public int findListCount(Integer pageSize);
}
@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),最后将这些信息设置到请求属性中转发给视图。

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 实现分页导航的功能

<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>

在这里插入图片描述

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部