你的位置:首页 > Java教程

[Java教程]JSP分页显示实例(基于Bootstrap)


首先介绍一款简单利落的分页利器:bootstrap-paginator

效果截图:

搜索记录

GitHub官方下载地址:https://github.com/lyonlai/bootstrap-paginator

备用下载地址:http://files.cnblogs.com/files/Dreamer-1/bootstrap-paginator-master.rar

下面就来详细介绍一下基于这款分页利器的JSP分页显示实现过程(注:相较于原网页我隐去了很多不必要的内容,本例只专注于分页显示的实现)

 

一:

为什么需要分页显示?

这篇博文的博主说得很透彻:http://blog.csdn.net/xiaoyousifang/article/details/5659667

 

二:

JSP页面部分,这里直接在JSP页面中用JDBC连接SqlServer2005数据库查询数据(实际实现里不建议把复杂的业务逻辑封装在JSP页面中,JSP页面应当只是负责显示;对客户端的响应、业务逻辑调用、结果转发都应该由Servlet来完成)

代码如下:

<%@ page import="PaginationExample.*" %><%@ page import="java.util.*"%><%@ page import="java.sql.*"%><%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%><%!  private static final int pageSize = 20;  //设定每页显示的记录条数(当前为每页显示20条记录)%><%    request.setCharacterEncoding("UTF-8");          //设定客户端提交给servlet的内容按UTF-8编码  response.setCharacterEncoding("UTF-8");          //设定servlet传回给客户端的内容按UTF-8编码  response.setContentType("text/html;charset=UTF-8");    //告知浏览器用UTF-8格式解析内容    String pageNoStr = request.getParameter("pageNoStr");  //接收客户端传递的要显示页数  int pageNo = 1;  //要显示的页数  int totalPages = 1;  //总页数    //检查、设置pageNo  if (pageNoStr != null && !pageNoStr.equals("")) {    try {      pageNo = Integer.parseInt(pageNoStr);            if (pageNo < 1) {        //pageNo小于1时默认显示第一页        pageNo = 1;      }    }    catch (NumberFormatException e) {      //获取到的pageNo(当前页面数)不合法时,默认显示第一页      pageNo = 1;    }  }  else {    //其他未获取到pageNo的情况都默认显示第一页    pageNo = 1;  }  /* ========================================连接数据库(获取总页数与当前页内要显示的观测记录)====================================== */        /* 获取数据库中将记录按指定条数(pageSize)分页后的总页数 */  Connection totalConn = null;  Statement totalStmt = null;  ResultSet totalRs = null;    try {    totalConn = DBUtil.getConnection();        //生成sql语句    String sqlGetTotalPages = "select count(*) from alldata";    //获取总记录条数    totalStmt = totalConn.createStatement();    totalRs = totalStmt.executeQuery(sqlGetTotalPages);    totalRs.next();    int countResult = totalRs.getInt(1);        //取得总页数    totalPages = countResult % pageSize == 0 ? countResult / pageSize : (int)(countResult / pageSize) + 1;            } catch (SQLException e) {    System.out.println("历史记录查询出错,操作未完成!");    e.printStackTrace();  } finally {    DBUtil.close(totalRs);    DBUtil.close(totalStmt);    DBUtil.close(totalConn);  }    /* 如果页数大于总页数,则默认显示最后一页 */  if (pageNo > totalPages) {    pageNo = totalPages;  }      /* 获取数据库中当前页内要显示的观测记录,使用一个List来盛装记录 */  List<Record> records = new ArrayList<Record>();      Connection conn = null;  PreparedStatement pstmt = null;  ResultSet rs = null;    int startIndex = (pageNo - 1) * pageSize + 1;  int endIndex = pageNo * pageSize;    try {    conn = DBUtil.getConnection();        String sql = "select * from (select row_number() over(order by data_taizhan_num, data_date asc) as 'num', * from alldata) as temp where num between " + startIndex + " and " + endIndex;    pstmt = conn.prepareStatement(sql);    rs = pstmt.executeQuery();    while (rs.next()) {      //取出每条记录的数据,并将其封装成Record对象      Record r = new Record();      r.setTaizhan_num(rs.getString(2));      r.setDate(rs.getTimestamp(3));      r.setTem(rs.getString(4));      r.setHum(rs.getString(5));      r.setPa(rs.getString(6));      r.setRain(rs.getString(7));      r.setWin_dir(rs.getString(8));      r.setWin_sp(rs.getString(9));                    records.add(r);    //将封装好的Record对象放入列表容器中    }      } catch (SQLException e) {    System.out.println("查询出错,操作未完成!");    e.printStackTrace();  } finally {    DBUtil.close(rs);    DBUtil.close(pstmt);    DBUtil.close(conn);  }System.out.println(totalPages);System.out.println(pageNo);/* ========================================数据库连接结束====================================== */  %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html lang="zh-CN">  <head>    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">  <%-- 在IE运行最新的渲染模式 --%>    <meta name="viewport" content="width=device-width, initial-scale=1">  <%-- 初始化移动浏览显示 --%>    <meta name="Author" content="Dreamer-1.">    <link rel="stylesheet" href="css/bootstrap.css">    <link rel="stylesheet" href="css/recordSearchResult.css">    <script type="text/javascript" src="js/jquery-1.12.3.min.js"></script>    <script type="text/javascript" src="js/bootstrap.min.js"></script>    <script type="text/javascript" src="js/bootstrap-paginator.min.js"></script>          <title>- 搜索记录 -</title>  </head>    <body>    <div class="container">      <div class="wrapper">        <!-- 使用表单展示数据记录 -->        <form class="form-area">           <table class="table table-striped table-hover" >           <%            if (records == null || records.size() == 0) {              out.println("<tr><td><h4><strong>没有符合要求的记录呢,不如换个搜索条件试试吧~</strong></h4></td></tr>");                        }            else {          %>                        <tr>                <td><h4><strong>观测台站</strong></h4></td>                          <%                Record r = records.get(0);                                  if (r.getTem() != null) {                  out.println("<td><h4><strong>温度(℃)</strong></h4></td>");                }                if (r.getHum() != null) {                  out.println("<td><h4><strong>湿度(%)</strong></h4></td>");                }                if (r.getPa() != null) {                  out.println("<td><h4><strong>压强(hPa)</strong></h4></td>");                }                if (r.getRain() != null) {                  out.println("<td><h4><strong>雨量(mm)</strong></h4></td>");                }                if (r.getWin_dir() != null) {                  out.println("<td><h4><strong>风向(°)</strong></h4></td>");                }                    if (r.getWin_sp() != null) {                  out.println("<td><h4><strong>风速(m/s)</strong></h4></td>");                }                              %>                            <td><h4><strong>观测时间</strong></h4></td>              </tr>          <%            }          %>              <%            if (records != null && records.size() != 0) {              for (Record r : records) {                      %>                          <tr>                  <td><%= r.getTaizhan_num() %></td>                    <%                  if (r.getTem() != null) {                    out.println("<td>" + r.getTem() + "</td>");                  }                  if (r.getHum() != null) {                    out.println("<td>"+ r.getHum() +"</td>");                  }                  if (r.getPa() != null) {                    out.println("<td>" + r.getPa() + "</td>");                  }                  if (r.getRain() != null) {                    out.println("<td>" + r.getRain() + "</td>");                  }                  if (r.getWin_dir() != null) {                    out.println("<td>" + r.getWin_dir() + "</td>");                  }                      if (r.getWin_sp() != null) {                    out.println("<td>" + r.getWin_sp() + "</td>");                  }          %>                          <td><%= r.getDate() %></td>                </tr>                    <%                            }          %>                            </table>                          <!-- 分页显示div -->                                                  <div align="center">               <ul class="pagination" id="paginator"></ul>             </div>                          </form>                              <%            }          %>            </div>    </div>       <script type='text/javascript'>      var options = {                    bootstrapMajorVersion: 3,  //bootstrap版本          size: 'normal',          itemTexts: function (type, page, current) {            switch (type) {            case "first":              return "首页";            case "prev":              return "<i class='fa fa-caret-left'></i> 上一页";            case "next":              return "下一页 <i class='fa fa-caret-right'></i>";            case "last":              return "末页";            case "page":              return page;            }          },          tooltipTitles: function (type, page, current) {            switch (type) {            case "first":              return "首页";            case "prev":              return "上一页";            case "next":              return "下一页";            case "last":              return "末页";            case "page":              return "第" + page + "页";            }          },          pageUrl: function(type, page, current){            return "showInfoSearchResult.jsp?pageNoStr="+page;  //跳转到选定页面          },          numberOfPages: 6,  //显示“第几页”的选项数目          currentPage: <%= pageNo %>,  //当前页数          totalPages: <%= totalPages %>  //总页数          }        $('#paginator').bootstrapPaginator(options);    </script>    </body></html>

 

三:

关于本例中用到的Record、DBUtil类:

Record类是一个用于封装数据的,对外仅提供get/set方法的普通Java类,其属性与数据库表中包含的字段一一对应,代码如下:

package PaginationExample;import java.sql.*;/** * 封装气象数据信息 * @author zhong * */public class Record {    private String taizhan_num;  //台站名  private String tem;      //温度  private String hum;      //湿度  private String pa;      //压强  private String rain;    //雨量  private String win_dir;    //风向  private String win_sp;    //风速  private Timestamp date;    //观测日期(原始格式)    /**   * 获取产生该观测记录的台站名称;   * @return 台站名称   */  public String getTaizhan_num() {    return taizhan_num;  }  /**   * 设置产生该观测记录的台站名称;   * @param taizhan_num 待设置台站名称   */  public void setTaizhan_num(String taizhan_num) {    this.taizhan_num = taizhan_num;  }  /**   * 获取温度;   * @return 温度值   */  public String getTem() {    return tem;  }  /**   * 设置温度;   * @param tem 待设置温度值   */  public void setTem(String tem) {    this.tem = tem;  }  /**   * 获取湿度;   * @return 湿度值   */  public String getHum() {    return hum;  }  /**   * 设置湿度;   * @param hum 待设置湿度值   */  public void setHum(String hum) {    this.hum = hum;  }  /**   * 获取压强;   * @return 压强值   */  public String getPa() {    return pa;  }  /**   * 设置压强;   * @param pa 待设置压强值   */  public void setPa(String pa) {    this.pa = pa;  }  /**   * 获取雨量;   * @return 雨量值   */  public String getRain() {    return rain;  }  /**   * 设置雨量;   * @param rain 待设置雨量值   */  public void setRain(String rain) {    this.rain = rain;  }  /**   * 获取风向;   * @return 风向值   */  public String getWin_dir() {    return win_dir;  }  /**   * 设置风向;   * @param win_dir 待设置风向值   */  public void setWin_dir(String win_dir) {    this.win_dir = win_dir;  }  /**   * 获取风速;   * @return 风速值   */  public String getWin_sp() {    return win_sp;  }  /**   * 设置风向;   * @param win_sp 待设置风向值   */  public void setWin_sp(String win_sp) {    this.win_sp = win_sp;  }  /**   * 获取观测日期;   * @return 观测日期   */  public Timestamp getDate() {    return date;  }  /**   * 设置观测日期;   * @param date 观测日期值   */  public void setDate(Timestamp date) {    this.date = date;  }  }

 

对应的alldata表部分数据截图:

捕获3

 

DBUtil类是一个数据库工具类,统一对外提供与数据库相关的Connection、Statement等,代码如下:

package PaginationExample;import java.sql.*;import org.apache.tomcat.jdbc.pool.DataSource;import org.apache.tomcat.jdbc.pool.PoolProperties;/** * 数据库工具类(采用了tomcat jdbc pool) * @author zhong * */public class DBUtil {    private static DataSource ds;    static {    //配置tomcat jdbc pool (连接池)    PoolProperties p = new PoolProperties();    p.setUrl("jdbc:sqlserver://localhost:1433; DatabaseName=weather");  //设置连接的url    p.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");  //载入数据库驱动    p.setUsername("sa");  //用于远程连接的用户名    p.setPassword("2003NianDeDiYiChangXue");  //密码    p.setJmxEnabled(true);    p.setTestWhileIdle(false);    p.setTestOnBorrow(true);    p.setValidationQuery("SELECT 1");    p.setTestOnReturn(false);    p.setValidationInterval(30000);    p.setTimeBetweenEvictionRunsMillis(30000);    p.setMaxActive(100);    p.setInitialSize(10);    p.setMaxWait(10000);    p.setRemoveAbandonedTimeout(60);    p.setMinEvictableIdleTimeMillis(30000);    p.setMinIdle(10);    p.setLogAbandoned(true);    p.setRemoveAbandoned(true);    p.setJdbcInterceptors(     "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+     "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");    ds = new DataSource();    ds.setPoolProperties(p);  }    private DBUtil() {}    /**   * 获取一个数据库连接(Connection);   * @return Database Connection   */  public static Connection getConnection() {    Connection conn = null;        try {            conn = ds.getConnection();    } catch (SQLException e) {      e.printStackTrace();    }        return conn;  }    /**   * 关闭传入的Connection;   * @param conn 待关闭的Connection   */  public static void close(Connection conn) {    try {      if (conn != null) {        conn.close();        conn = null;      }    } catch (SQLException e) {      e.printStackTrace();    }  }  /**   * 关闭传入的Statement;   * @param stmt  待关闭的Statement   */  public static void close(Statement stmt) {    try {      if (stmt != null) {        stmt.close();        stmt = null;      }    } catch (SQLException e) {      e.printStackTrace();    }  }    /**   * 关闭传入的ResultSet;   * @param rs  待关闭的ResultSet   */  public static void close(ResultSet rs) {    try {      if (rs != null) {        rs.close();        rs = null;      }    } catch (SQLException e) {      e.printStackTrace();    }  }  }

 

四:

补充说明:

①:SQLServer实现分页时需借助ROW_NUMBER()函数,以生成一个单独记录了行号的列,方便后面分页时取出对应行号区间段的记录。例:

select * from alldata 执行效果:

捕获

 

select row_number() over(order by data_taizhan_num, data_date asc) as 'num', * from alldata 执行效果:

捕获2

 

看到了吧,最前面多了一列存储了行号的字段名为num的列;

(如果表内主键id是自动递增的数字的话,也可以直接用id来分段取出记录,但前提是id必须连续自动递增

关于更多ROW_NUMBER()函数实现分页的信息请参考:http://www.cnblogs.com/ajun/archive/2012/12/12/2814780.html

 

 

②:MySQL分页实现起来简单很多,直接使用limit关键字即可。例:

select * from table1 order by id asc limit 3, 2  意即将表table1中的数据按id值排序(升序)后,从第三行开始,取后面的两行记录(即第四、五行记录)

 

 

③:关于bootstrap-paginator的具体使用方法可以参考官方的文档(位于解压后的document文件夹内),官方文档写得很棒,简单易懂。

在使用时要注意对于bootstrap V3版本来说,要使用<ul>标签来显示bootstrap-paginator,并在配置项里注明所用bootstrap的版本(参考我jsp示例页面的写法)。

bootstrap V2版本直接使用示例文档中的<div>标签即可)

 

④:分页常用公式:设要显示的页数为 n ,每页显示 m 条数据,则(数据库中)待取数据的开始位置(即jsp示例中的startIndex)为: (n-1)*m+1,终止位置(endIndex)为:n*m

 

⑤:源码下载:http://files.cnblogs.com/files/Dreamer-1/PaginationExample.rar