鸡汤文项目相关知识点网站制作

Java Web 之分页技术

2016-12-01  本文已影响1207人  廖少少

本文包括:

1、分页技术概述

2、实现分页

3、完善分业——分页工具条

4、几种常见的分页工具条

1、分页技术概述

  1. 物理分页

    • 在SQL查询时,从数据库只查询分页需要的数据

    • 通常,对于不同数据库有不同的物理分页语句

      MySQL 使用limit;
      SQLServer 使用top;
      Oracle使用rowNum

    • 对于MySQL,采用limit关键字

    • 例如:查询第11-20条数据,SQL语句:

        select * from user limit 10,10;
      
    • demo:

        @Test
        public void demo2() throws SQLException {
            // 物理分页 ,根据数据库关键字 limit 查询需要数据 查询150-200条
            String sql = "select * from customer order by name limit ?,?";
            int start = 150 - 1; // 开始索引 开始条数-1
            int len = 200 - 150 + 1; // 结束条数-开始条数 +1
            QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
            List<Customer> customers = queryRunner.query(sql,
                    new BeanListHandler<Customer>(Customer.class), start, len);
            System.out.println("size:" + customers.size());
            for (Customer customer : customers) {
                System.out.println(customer.getName());
            }
        }
      
  2. 逻辑分页

    • 在SQL查询时,先从数据库查询出所有数据的结果集

    • 在Java代码中通过逻辑语句获得分页需要的数据

    • 例如:查询第11-20条数据:

        userList.subList(10,20)
      
    • demo:

        @Test
        public void demo3() throws SQLException {
            // 逻辑分页 150 - 200
            String sql = "select * from customer order by name";
            QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
            List<Customer> customers = queryRunner.query(sql,
                    new BeanListHandler<Customer>(Customer.class));
      
            customers = customers.subList(150 - 1, 200);
            System.out.println("size:" + customers.size());
            for (Customer customer : customers) {
                System.out.println(customer.getName());
            }
        }
      
  3. 性能上,物理分页明显好于逻辑分页,尽量使用物理分页。

2、实现分页

  1. 分类查询UML图

    UML绘制软件:Jude(Java and UML Developer's Environment)

    Jude教程:http://blog.csdn.net/shesunshine/article/details/5670862

  2. 在JSP页面新增a链接,其中pageQuery为PageQueryServlet的URL:

     <a href="XX/pageQuery?pNum=1">分页查询</a>
    
  3. PageQueryServlet:

     public class PageQueryServlet extends HttpServlet {
     
         public void doGet(HttpServletRequest request, HttpServletResponse response)
                 throws ServletException, IOException {
             // 获得客户端提交页码
             String pNumStr = request.getParameter("pNum");
             int pNum = Integer.parseInt(pNumStr);// 如果不是数字报错
     
             // 将页码传递 业务层
             CustomerService customerService = new CustomerService();
             List<Customer> customers = customer Service.pageQuery(pNum);
     
             // 传递结果进行显示
             request.setAttribute("customers", customers); 
             request.getRequestDispatcher("/list.jsp").forward(request,
                     response);
         }
     
         public void doPost(HttpServletRequest request, HttpServletResponse response)
                 throws ServletException, IOException {
             doGet(request, response);
         }
     
     }
    
  4. CustomerService中设置常量、新增pageQuery(int pNum)方法:

     public static final int NUMBERPAGE = 10; // 设置每页条数为常量
     public List<Customer> pageQuery(int pNum){
         // 根绝页码和每页条数计算开始索引
         int start = (pNum - 1) * NUMBERPAGE;
     
         // 调用DAO进行分页查询
         CustomerDAO customerDAO = new CustomerDAO();
         return customerDAO.findByPage(start, NUMBERPAGE);
     }
    
  5. CustomerDAO中新增findByPage(int pNum, int numberPage)方法:

     public List<Customer> findByPage(int start, int numberPage){
         String sql = "select * from customer limit ?,?";
         QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource()); // 利用DBUtils开源工具进行JDBC编程
         try{
             return queryRunner.query(sql,new BeanListHandler<Customer>(Customer.class));
         } catch(SQLException e){
             e.printStackTrace();
         }
         return null;
     }
    

3、完善分页——分页工具条

  1. 实现分页中的虽然能提供分页,但是需要手动在地址栏输入第几页,这显然对用户极不友好,不过别急,上面只是实现了分页的效果。

  2. 很多网站都提供了分页功能,分页页面效果:

    首页 上一页 1 2 3 4 5 6 7 下一页 尾页

  3. 上面的工具条只适用页数很少的业务,google查询的页数有上万页,不可能全部显示在页面上,也不可能提供“尾页”这个选项,所以以当前页为中心,提供前后5页的跳转链接,下面是一种可借鉴的分页工具条(假设当前页数为10):

    上一页 5 6 7 8 9 10 11 12 13 14 15 下一页

    谷歌的分页工具条:


  4. 现在一般的做法,分页查询都会用单独类来封装查询结果

    PageBean ----- 在业务层返回数据返回PageBean对象

     public class PageBean {
         public static final int NUMPERPAGE = 10; // 每页多少条
         private int pNum; // 当前第几页
         private int totalPageNum; // 总页数
         private int totalRecordNum; // 总记录数
         private List<Customer> customers; // 结果数据
     
         public int getpNum() {
             return pNum;
         }
     
         public void setpNum(int pNum) {
             this.pNum = pNum;
         }
     
         public int getTotalPageNum() {
             return totalPageNum;
         }
     
         public void setTotalPageNum(int totalPageNum) {
             this.totalPageNum = totalPageNum;
         }
     
         public int getTotalRecordNum() {
             return totalRecordNum;
         }
     
         public void setTotalRecordNum(int totalRecordNum) {
             this.totalRecordNum = totalRecordNum;
         }
     
         public List<Customer> getCustomers() {
             return customers;
         }
     
         public void setCustomers(List<Customer> customers) {
             this.customers = customers;
         }
     
     }
    
  5. 于是,在CustomerService修改pageQuery(int pNum)方法:

     public static final int NUMBERPAGE = 10; // 设置每页条数为常量
     public PageBean pageQuery(int pNum) {
         // 根据页码 和 每页条数 计算开始索引
         int start = (pNum - 1) * NUMPERPAGE;
    
         PageBean bean = new PageBean();
    
         // 封装当前页码
         bean.setpNum(pNum);
    
         // 调用DAO进行分页查询 --- 结果数据
         CustomerDAO customerDAO = new CustomerDAO();
         List<Customer> customers = customerDAO.findByPage(start,
                 PageBean.NUMPERPAGE);
         bean.setCustomers(customers);
    
         // 封装总记录条数,findTotalRecordNum()方法见下文
         int totalRecordNum = customerDAO.findTotalRecordNum();
         bean.setTotalRecordNum(totalRecordNum);
    
         // 计算总页数,很常用!!!
         int totalPageNum = (totalRecordNum + PageBean.NUMPERPAGE - 1)
                 / PageBean.NUMPERPAGE;
         bean.setTotalPageNum(totalPageNum);
    
         return bean;
     }
    
  6. 在CustomerDAO中新增findTotalRecordNum()方法:

     // 查询总记录条数
     public int findTotalRecordNum() {
         String sql = "select count(*) from customer";
         QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
         // ScalarHandler
         try {
             // 因为结果集只有一行一列,所以这里应该用ScalarHandler
             long totalRecordNum = (Long) queryRunner.query(sql,
                     new ScalarHandler(1));
             return (int) totalRecordNum; // int表示的范围足够了
         } catch (SQLException e) {
             e.printStackTrace();
         }
         return 0;
     }
    
  7. 于是,在PageQueryServlet中修改:

    修改前:

     List<Customer> customers = customer Service.pageQuery(pNum);
    
     // 传递结果进行显示
     request.setAttribute("customers", customers); 
     request.getRequestDispatcher("/list.jsp").forward(request,
             response);
    

    修改后:

     PageBean pageBean = customerService.pageQuery(pNum);
    
     // 传递结果进行显示
     request.setAttribute("pageBean", pageBean); // ${pageBean}
     request.getRequestDispatcher("/page_list.jsp").forward(request,
             response);
    
  8. 接下来就是编写JSP页面:

    • 预期效果:

    • 现在的问题是:根本不知道哪个是当前页,所以还要改进一下foreach中的代码:

            <!-- 当前页不显示链接,即可知道哪个是当前页 -->
            <!-- 利用foreach循环输出 -->
            <c:forEach begin="${begin}" end="${end}" var="i">
                <c:if test="${pageBean.pNum==i}">
                    ${i }
                </c:if>
                <c:if test="${pageBean.pNum!=i}">
                    <a href="/pageQuery?pNum=${i }">${i } </a>
                </c:if>    
            </c:forEach>
      
    • 现在即可清晰的显示当前页了(可用CSS/JavaScript进一步美化界面,功能实现到此为止)

    • 实现输入页码跳转,在尾页代码的后面加入input:

            <input type="text" id="pNum" size="2"/><input type="button" value="go" onclick="jump();"/>
      

      对应的JavaScript代码:

        <script type="text/javascript">
            function jump(){
                // 获得用户输入页码
                var pNum = document.getElementById("pNum").value;
                location.href="/pageQuery?pNum=" + pNum;
            }
        </script>
      

4、几种常见的分页工具条

上一篇下一篇

猜你喜欢

热点阅读