在系统中如何实现分页显示。

参考解答

分页分为前台和后台,后台关心的是分页的SQL如何编写,前台关心的是数据如何分页显示。

分页的目的是减少每次查询的数据量,在数据量大时减轻数据库访问压力。

分页的类型可以分为逻辑分页和物理分页,使用sql语句查询部分数据称为物理分页(推荐),将数据全部查询出来用java代码进行分页称为逻辑分页(不推荐)。

1. 后台分页

1) sql实现

Oralce(假设号参数为page,每页记录数参数为size)

select a.* from ( 
  select b.*, rownum rn from ( select * fromorder by ... ) b    
    where rownum <= ${page*size} 
  ) a 
where rn > ${(page-1)*size}

查询第一页可以简化为:

select * from (
  ( select * fromorder by ... )
) where rownum <= ${page*size}

MySQL(假设号参数为page,每页记录数参数为size)

select * fromorder by ... limit ${(page-1)*size}, ${size}

查询第一页可以简化为:

select * fromorder by ... limit ${size}

2) po实现

package po; public class Emp { private int empno; private String ename; private double sal; public int getEmpno() { return empno; } public void setEmpno(int empno) { this.empno = empno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } }

3) dao实现

package dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import po.Emp; public class EmpDao { static{ try { Class.forName("oracle.jdbc.OracleDriver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public int count() { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "scott", "tiger"); ps = conn.prepareStatement("select count(*) from emp"); rs = ps.executeQuery(); rs.next(); int count = rs.getInt(1); return count; } catch (Exception e) { throw new RuntimeException(e); } finally { if (conn != null) { try { conn.close(); } catch (SQLException e) { } } } } public List<Emp> find(int page, int rows) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "scott", "tiger"); ps = conn.prepareStatement("select a.* from ( select b.*, rownum rn from (select * from emp order by sal desc) b where rownum <= ? ) a where rn > ?"); ps.setInt(1, page * rows); ps.setInt(2, (page - 1) * rows); rs = ps.executeQuery(); List<Emp> list = new ArrayList<>(rows); while (rs.next()) { Emp e = new Emp(); e.setEmpno(rs.getInt("empno")); e.setEname(rs.getString("ename")); e.setSal(rs.getDouble("sal")); list.add(e); } return list; } catch (Exception e) { throw new RuntimeException(e); } finally { if (conn != null) { try { conn.close(); } catch (SQLException e) { } } } } }

4) 分页栏抽象:

考虑了最大页数,例如最大页数控制在10,[]内为当前页:

[1]     2      3      4      5      6      7      8      9      10     
 1     [2]     3      4      5      6      7      8      9      10     
 1      2     [3]     4      5      6      7      8      9      10     
 1      2      3     [4]     5      6      7      8      9      10     
 1      2      3      4     [5]     6      7      8      9      10     
 1      2      3      4      5     [6]     7      8      9      10     
 2      3      4      5      6     [7]     8      9      10     11     
 3      4      5      6      7     [8]     9     10      11     12     
 4      5      6      7      8     [9]    10     11      12     13
package vo; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Objects; public class Pagebar<T> implements Iterable<T> { @Override public String toString() { return "Pagebar [list=" + list + ", count=" + count + ", page=" + page + ", rows=" + rows + ", total=" + total + ", pageMax=" + pageMax + ", pageLeftMax=" + pageLeftMax + ", begin=" + begin + ", end=" + end + "]"; } private List<T> list; private int count; private int page; private int rows; private int total; private int pageMax; private int pageLeftMax; private int begin; private int end; @Override public Iterator<T> iterator() { return list.iterator(); } public List<T> getList() { return list; } public int getCount() { return count; } public int getPage() { return page; } public int getRows() { return rows; } public int getTotal() { return total; } public int getPageMax() { return pageMax; } public int getPageLeftMax() { return pageLeftMax; } public int getBegin() { return begin; } public int getEnd() { return end; } private Pagebar(List<T> list, int count, int page, int rows, int total, int pageMax, int pageLeftMax, int begin, int end) { super(); this.list = list; this.count = count; this.page = page; this.rows = rows; this.total = total; this.pageMax = pageMax; this.pageLeftMax = pageLeftMax; this.begin = begin; this.end = end; } public static class PagebarBuilder<T> { private List<T> list; // 当前页记录 private Integer count; // 总记录数 private int page = 1; // 页号 private int rows = 10; // 每页行数 private int total; // 总页数 private int pageMax = 10; // 最多显示页数 private int pageLeftMax = 5; // 当前页左侧最多显示页数 private int begin; // 起始页号 private int end; // 结束页号 public PagebarBuilder<T> setPage(int page) { this.page = page; return this; } public PagebarBuilder<T> setRows(int rows) { this.rows = rows; return this; } public PagebarBuilder<T> setPageMax(int pageMax) { this.pageMax = pageMax; return this; } public PagebarBuilder<T> setPageLeftMax(int pageLeftMax) { this.pageLeftMax = pageLeftMax; return this; } public PagebarBuilder<T> setListAndCount(List<T> list, Integer count) { this.list = list; this.count = count; return this; } protected void calculateBeginEnd() { int right = pageMax - pageLeftMax - 1; if (total <= pageMax) { begin = 1; end = total; } else { if (page <= pageLeftMax + 1) { begin = 1; end = pageMax; } else { if (total - page <= right) { begin = total - (pageMax - 1); end = total; } else { begin = page - pageLeftMax; end = page + right; } } } } private void calculateTotal() { if (count % rows == 0) { total = count / rows; } else { total = count / rows + 1; } } public Pagebar<T> build() { Objects.requireNonNull(list, "list can't be null"); Objects.requireNonNull(count, "count can't be null"); calculateTotal(); calculateBeginEnd(); Pagebar<T> pagebar = new Pagebar<>(list, count, page, rows, total, pageMax, pageLeftMax, begin, end); return pagebar; } } public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2); Integer count = 100; for (int i = 1; i < 10; i++) { Pagebar<Integer> pb = new PagebarBuilder<Integer>().setPage(i).setRows(2).setListAndCount(list, count).build(); for (int p = pb.getBegin(); p <= pb.getEnd(); p++) { if (p == i) { System.out.print("[" + p + "]\t"); } else { System.out.print(" " + p + " \t"); } } System.out.println(); } } }

2. 前台显示:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>分页示例</title> <style type="text/css"> #empTBL{border-collapse: collapse;width:50%;margin:0 auto;} #empTBL tr{border: 1px black solid; } #empTBL td{padding: 15px;} #pagebar {margin:0 auto;width:50%;text-align: center;} #pagebar a {margin:0 8px;} #pagebar span{margin:0 8px; color: blue;} </style> </head> <body> <table id="empTBL"> <tr> <td>编号</td><td>姓名</td><td>工资</td> </tr> <c:forEach items="${pagebar.list}" var="emp"> <tr> <td>${emp.empno}</td><td>${emp.ename}</td><td>${emp.sal}</td> </tr> </c:forEach> </table> <div id="pagebar"> <c:forEach begin="${pagebar.begin}" end="${pagebar.end}" var="n"> <c:if test="${n==pagebar.page}"> <span>[第${n}页]</span> </c:if> <c:if test="${n!=pagebar.page}"> <a href="list?page=${n}">第${n}页</a> </c:if> </c:forEach> </div> </body> </html>

效果:


results matching ""

    No results matching ""