什么是分页?怎么实现分页的实现?

Javaweb 专栏收录该内容
19 篇文章 2 订阅

分页的实现

分页简介
分页(英语:Paging),是一种操作系统里存储器管理的一种技术,可以使电脑的主存可以使用存储在辅助存储器中的数据。操作系统会将辅助存储器(通常是磁盘)中的数据分区成固定大小的区块,称为“页”。当不需要时,将分页由主存(通常是内存)移到辅助存储器;当需要时,再将数据取回,加载主存中。相对于分段,分页允许存储器存储于不连续的区块以维持文件系统的整齐。分页是磁盘和内存间传输数据块的最小单位,在Java中是一种特别常见的现象,下面我将一点一点的带着大家来分析一下分页。

理解分页
分页无非就是在服务器端得到数据,然后以固定的条数来写到浏览器端进行显示的过程,要想写好分页,不非就是首先明确,一个分页功能需要包含什么样的变量,这些变量该怎么获得,是从前端页面传过来呢,还是从后端获取的呢,下面咱们来简单的了解一下:
1.totalCount :总的数据的条数,显然易见,由于数据库的数据可以变化,显然该数据需要从后台获取。
2.totalPage:总的页数,由于总的数据是从数据库中查询出来的,每页多少条数据都可以是事先知道的,所以,从后台获取
3.list 每页的数据,显然是从后台获取的
4.currentPage当前页,显然是从前台获取的,因为每次大家需要点击不同的页数,传递过来的数据都是不一样的
5rows.每页多少条数据,可以从前台获取也可以从后台获取,我建议从后台获取,可以将其存到配置文件中,可以通过获取到不同的标准,符合Java的编程理念

细节优化和讲解
首先将rows写到web.xml文件中对应的分页对应的servlet中,再通过getServletConfig().getInitParameter()初始化的时候获取:
在这里插入图片描述
各变量的简单的书写流程,大家可以简单理解一下,下面会详细解答
在这里插入图片描述
流程分析
1.首先从前台获取到当前页
2.利用service查询PageBean
3.将pageBean存到request域对象中
4.转发到list.jsp,利用jstl和el表达式来实现数据的显示
在这里插入图片描述
代码体现
将分页的详细属性封装成JavaBean,便于存到域对象中,获取其数据值

package cn.ujiuye.domain;

import java.util.List;

/**
 * 分页的javaBean
 */
public class PageBean<T> {
    private int totalCount;  //总的记录数
    private int totalPage;   //总的页码
    private List<T> list;    //每页的数据
    private int currentPage; //当前页
    private int rows;        //每页显示的条数

    public int getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public int getRows() {
        return rows;
    }

    public void setRows(int rows) {
        this.rows = rows;
    }

    @Override
    public String toString() {
        return "PageBean{" +
                "totalCount=" + totalCount +
                ", totalPage=" + totalPage +
                ", list=" + list +
                ", currentPage=" + currentPage +
                ", rows=" + rows +
                '}';
    }
}

首先书写一个findProductByPageServlet,实现前端和后端的数据的交互,我认为首先写后台代码,再将所需要的当前页的currentPage手动通过地址栏手动传入数据,这样可以最快进入数据的书写流程,可以先检查后端代码是不是实现的没有问题
在这里插入图片描述

package cn.ujiuye.web.servlet;
import cn.ujiuye.domain.PageBean;
import cn.ujiuye.domain.Product;
import cn.ujiuye.service.ProductService;
import cn.ujiuye.service.impl.ProductServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class FindProductByPageServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取请求参数
        String currentPage = request.getParameter("currentPage");
        String rows = getServletConfig().getInitParameter("rows");
        //判断从其他的页面传递过来的时候,这个时候需要做对其当前页的判断
        if (currentPage == null || "".equals(currentPage)){
            currentPage = "1";
        }

        System.out.println("当前页码是:"+currentPage);
        System.out.println("每页的条数是:"+ rows);

        //2.调用service进行查询
        ProductService service = new ProductServiceImpl();
        PageBean<Product> pb = service.findUserByPage(currentPage,rows);

        System.out.println(pb.getTotalPage()+"***************");

        //3.将pageBean存入到域对象中
        request.setAttribute("pb",pb);
        //4.转发到list.jsp页面中去
        request.getRequestDispatcher("/list.jsp").forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }


}

在service层实现数据的业务逻辑的处理,我是用了接口的思想来实现的,把数据存入到JavaBean的时候,方便调用,将其分页的各项需求的内容都写入到JavaBean中,从前端获取的当前页,从servlet中获取的每页有多少条数据,通过dao来查询数据库中一共有多少条数据,通过计算获取其一共多少页,返回每一页有多少条数据,这些数据在service层都传入到JavaBean中,用于封装起来了

  /**
     * 分页查询
     * @param _currentPage
     * @param _rows
     * @return
     */
    @Override
    public PageBean<Product> findUserByPage(String _currentPage, String _rows) {
        int currentPage = Integer.parseInt(_currentPage); //当前页数
        int rows = Integer.parseInt(_rows);               //每页多少条数据

        if (currentPage <= 1){
            currentPage = 1;
        }
        //1.创建一个空的PageBean对象
        PageBean<Product> pb =  new PageBean<Product>();
        //2.设置参数
        pb.setCurrentPage(currentPage);
        pb.setRows(rows);

        //3.使用dao查询获取总数据数
        int totalCount = dao.findTotalCount();
        System.out.println(totalCount);

        pb.setTotalCount(totalCount);
        //4.调用dao查询每页List集合中的详情
        int start = (currentPage - 1) * rows;
        List<Product> list = dao.findByPage(start,rows);
        pb.setList(list);

        //5.计算出总页码
        int totalPage = totalCount % rows == 0 ? totalCount / rows : totalCount / rows + 1;
        pb.setTotalPage(totalPage);

        return pb;
    }

在dao层中实现每页数据的显示和总记录的查询

 /**
     * 返回总记录数
     * @return
     */
    @Override
    public int findTotalCount() {
        //1.定义sql
        String sql = " select count(*) from product ";
        return template.queryForObject(sql,Integer.class);
    }

    /**
     * 分页操作,返回每一页的数据
     * @param start
     * @param rows
     * @return
     */
    @Override
    public List<Product> findByPage(int start, int rows) {
        //1.定义sql
        String sql = "select * from product limit ?,? ";
        return template.query(sql,new BeanPropertyRowMapper<Product>(Product.class),start,rows);
    }

这些完成后就开始了前端页面的书写,主要就是说从域对象中获取需要的值,然后利用jstl和el表达式来获取其值,从而达到显示的效果,注意上一页和下一页的写法和对于一些特别的地方的控制,在这里就不多介绍了,我还加入了bootstrap让页面更加漂亮了,下面给大家显示一个前端的源码和相应的显示结果

 <%--分页栏显示出来--%>
     <nav aria-label="Page navigation" style="text-align: center">
         <ul class="pagination pagination-lg">

             <c:if test="${pb.currentPage == 1}">
                 <li class="disabled">
             </c:if>
             <c:if test="${pb.currentPage != 1}">
                 <li>
             </c:if>

                 <a href="${pageContext.request.contextPath}/findProductByPageServlet?currentPage=${pb.currentPage - 1}" aria-label="Previous">
                     <span aria-hidden="true">&laquo;</span>
                 </a>
             </li>


             <c:forEach begin="1" end="${pb.totalPage}" var="i">

                 <c:if test="${pb.currentPage == i}">
                     <li class="active"><a href="${pageContext.request.contextPath}/findProductByPageServlet?currentPage=${i}">${i}</a></li>
                 </c:if>
                 <c:if test="${pb.currentPage != i}">
                     <li><a href="${pageContext.request.contextPath}/findProductByPageServlet?currentPage=${i}">${i}</a></li>
                 </c:if>

             </c:forEach>

             <c:if test="${pb.currentPage == pb.totalPage}">
                 <li class="disabled">
                     <a aria-label="Next">
                         <span aria-hidden="true">&raquo;</span>
                     </a>
                 </li>
             </c:if>

             <c:if test="${pb.currentPage != pb.totalPage}">
                 <li>
                     <a href="${pageContext.request.contextPath}/findProductByPageServlet?currentPage=${pb.currentPage + 1}" aria-label="Next">
                         <span aria-hidden="true">&raquo;</span>
                     </a>
                 </li>
             </c:if>


             <span style="font-size: 25px;margin-left: 5px">
                    &nbsp;&nbsp;共${pb.totalCount}条数据,共${pb.totalPage}页
             </span>
         </ul>
     </nav>

在这里插入图片描述
总结:希望大家都可以认真来确定自己是否学会了,是否可以真的能够实现自己的功能,自己可以来写自己想要的,自己要具备可以不改变的功能,能够对知识有一个真实的认识,我写的好的,大家多多指教,欢迎评论和点赞,希望要源码的私聊我

评论 1 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:创作都市 设计师:CSDN官方博客 返回首页

打赏作者

superliug

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值