首先介紹一款簡單利落的分頁利器:bootstrap-paginator
效果截圖:
<%@ 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表部分數據截圖:
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 執行效果:
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