JSP基于Bootstrap分页显示实例解析

首先介绍一款简单利落的分页利器:bootstrap-paginator,可以参考:Bootstrap Paginator分页插件使用方法详解 这篇文章进行学习。
效果截图:

 

GitHub官方下载地址:https://github.com/lyonlai/bootstrap-paginator
 下面就来详细介绍一下基于这款分页利器的JSP分页显示实现过程(注:相较于原网页我隐去了很多不必要的内容,本例只专注于分页显示的实现)

一、为什么需要分页显示?
 这篇博文说得很透彻:分页技术原理与实现之分页的意义及方法(一)

二、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 records = new ArrayList(); 
 
 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);
/* ========================================数据库连接结束====================================== */
 
%>



 
 
  <%-- 在IE运行最新的渲染模式 --%>
  <%-- 初始化移动浏览显示 --%>
 

 
 

 
 
 
 
 - 搜索记录 -
 
 
 

 
<% if (records == null || records.size() == 0) { out.println(""); } else { %> <% Record r = records.get(0); if (r.getTem() != null) { out.println(""); } if (r.getHum() != null) { out.println(""); } if (r.getPa() != null) { out.println(""); } if (r.getRain() != null) { out.println(""); } if (r.getWin_dir() != null) { out.println(""); } if (r.getWin_sp() != null) { out.println(""); } %> <% } %> <% if (records != null && records.size() != 0) { for (Record r : records) { %> <% if (r.getTem() != null) { out.println(""); } if (r.getHum() != null) { out.println(""); } if (r.getPa() != null) { out.println(""); } if (r.getRain() != null) { out.println(""); } if (r.getWin_dir() != null) { out.println(""); } if (r.getWin_sp() != null) { out.println(""); } %> <% } %>

没有符合要求的记录呢,不如换个搜索条件试试吧~

观测台站

温度(℃)

湿度(%)

压强(hPa)

雨量(mm)

风向(°)

风速(m/s)

观测时间

<%= r.getTaizhan_num() %>" + r.getTem() + ""+ r.getHum() +"" + r.getPa() + "" + r.getRain() + "" + r.getWin_dir() + "" + r.getWin_sp() + "<%= r.getDate() %>
    <% } %>

    三、关于本例中用到的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表部分数据截图:

    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()函数,以生成一个单独记录了行号的列,方便后面分页时取出对应行号区间段的记录。例:

    JSP基于Bootstrap分页显示实例解析_第1张图片

    看到了吧,最前面多了一列存储了行号的字段名为num的列;
     (如果表内主键id是自动递增的数字的话,也可以直接用id来分段取出记录,但前提是id必须连续且自动递增)
     关于更多ROW_NUMBER()函数实现分页的信息请参考:SQL Server使用row_number分页的实现方法

    ②:MySQL分页实现起来简单很多,直接使用limit关键字即可。例:
     select * from table1 order by id asc limit 3, 2  意即将表table1中的数据按id值排序(升序)后,从第三行开始,取后面的两行记录(即第四、五行记录)
    ③:关于bootstrap-paginator的具体使用方法可以参考官方的文档(位于解压后的document文件夹内),官方文档写得很棒,简单易懂。
     在使用时要注意对于bootstrap V3版本来说,要使用

      标签来显示bootstrap-paginator,并在配置项里注明所用bootstrap的版本(参考我jsp示例页面的写法)。
       (bootstrap V2版本直接使用示例文档中的
      标签即可)
       ④:分页常用公式:设要显示的页数为 n ,每页显示 m 条数据,则(数据库中)待取数据的开始位置(即jsp示例中的startIndex)为: (n-1)*m+1,终止位置(endIndex)为:n*m

      如果大家还想深入学习,可以点击这里进行学习,再为大家附3个精彩的专题:

      Bootstrap学习教程

      Bootstrap实战教程

      Bootstrap插件使用教程

      以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    你可能感兴趣的:(JSP基于Bootstrap分页显示实例解析)