JSP分頁顯示資料
- 分頁實作
-
- 背景
- 前台
分頁實作
實作分頁的方式有多種,例如将所有的查詢結果以集合等形式儲存在記憶體中,翻頁時從中取出一頁所需要的資料顯示。這種方式有兩個主要缺點;一是使用者看到的可能是過期的資料;二是如果資料量非常大,查詢一次資料集會耗費很長時間,并且存儲的資料也會占用大量記憶體開銷。
另一種做法是每次翻頁時隻從資料庫檢索出本頁需要的資料。雖然每次翻頁都查詢資料庫,但查詢出的記錄結果相對較少,總體開銷不大,再配以連接配接池技術及其其他查詢優化,可以達到比較高的效率。下面以mysql資料庫為背景資料庫,以分頁實作并且顯示分頁資料。
不同資料庫廠商實作分頁的SQl語句之間存在差異,是以在實際應用中根據資料庫的不同,需要修改相應的SQL語句。
實作資料的分頁顯示,需要以下幾個關鍵步驟:
(1) 确定每頁顯示的資料數量。
(2) 計算顯示的總頁數。
(3) 編寫SQL語句。
背景
1.确定每頁顯示的資料數量
根據實際頁面設計,确定在資料清單中每次顯示多少條記錄,即每次從資料庫中需要查詢出多少條記錄用于頁面顯示,通常這個數量可以在開發時定義好,也可以由使用者來選擇。
2.計算顯示的頁數
既然要進行分頁顯示,還需要清楚按照每頁顯示的記錄數量總共會産生多少頁資料。在頁面中顯示的記錄數量是已知的,而資料庫中符合展示條件的記錄總數是未知的,是以要想得到總頁數,需要經過以下幾個步驟。
(1) 通過查詢擷取符合展示條件的總記錄,可以借助count()聚合函數實作,
(2) 有了需要展示的記錄總數後,就可以根據每頁顯示的記錄條數計算共需要劃分多少頁。基于友善代碼管理的考慮,将有關分頁的資料分裝到一個Page類中,其中包括每頁顯示的資料數量,資料的總數量,顯示的總頁數,目前的頁碼,每頁顯示的資料集合。
類:
package org.news.util;
import java.util.List;
import org.news.entity.News;
public class Page {
// 總頁數
private int totalPageCount = 0;
// 頁面大小,即每頁顯示記錄數
private int pageSize = 5;
// 記錄總數
private int totalCount;
// 目前頁碼
private int currPageNo = 1;
// 每頁新聞集合
private List<News> newsList;
public int getCurrPageNo() {
if (totalPageCount == 0)
return 0;
return currPageNo;
}
public void setCurrPageNo(int currPageNo) {
if (currPageNo > 0)
this.currPageNo = currPageNo;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
if (pageSize > 0)
this.pageSize = pageSize;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
if (totalCount > 0) {
this.totalCount = totalCount;
// 計算總頁數
totalPageCount = this.totalCount % pageSize == 0 ? (this.totalCount / pageSize)
: (this.totalCount / pageSize + 1);
}
}
public int getTotalPageCount() {
return totalPageCount;
}
public void setTotalPageCount(int totalPageCount) {
this.totalPageCount = totalPageCount;
}
public List<News> getNewsList() {
return newsList;
}
public void setNewsList(List<News> newsList) {
this.newsList = newsList;
}
}
3.編寫SQl語句
實作資料分頁顯示的關鍵是如何編寫SQl查詢語句,MySQL資料庫中,可以使用LIMT字句實作分頁需求。假如每頁顯示三條記錄,若要是顯示第一頁記錄,則SQL語句如下:
這段語句中limit的字句的兩個參數分别代表起始行偏移量和最大傳回行數。最大傳回行數相當于每頁顯示的記錄數,是一個固定值,而每頁資料起始行的偏移量是動态的,應該如何确定呢?假設每條顯示三條,取第一頁資料時,不需要偏移,即起始偏移是0;而第二頁則偏移是在3條之後才能取得值;第三條就是偏移2*3條記錄。是以我們可以得出一個結論。
起始偏移量 = (目前頁頁碼數-1) * 每頁顯示的記錄數
是以SQL語句可以這樣進行表示:
select * from news limit (目前頁頁碼-1)*每頁顯示的記錄數,每頁現實的記錄數
剩下的就是dao層的邏輯了。
前台
在分頁功能測試成功之後,下面擷取資料在jsp頁面進行顯示。
首先分析在JSP頁面中如何進行分頁的設定。
(1) 确定目前的頁:試想一下,當頁面打開的時候,應該顯示第幾頁?肯定是第一頁,但如果頁面時通過使用者點選分頁執行查詢後顯示的結果,目前的頁碼還是第一頁嗎?答案是不确定的,是以我們需要在請求的時候設定一個pageindex 變量用來表示目前的頁碼。如果這個變量不存在,則預設目前頁為第一頁;否則目前頁為pageIndex變量的值。
<%
String pageIndex = request.getParameter("pageIndex");// 獲得目前頁數
if (pageIndex == null
|| (pageIndex = pageIndex.trim()).length() == 0) {
pageIndex = "1";
}
int currPageNo = Integer.parseInt(pageIndex);
%>
(2) 分頁的設定:有了目前頁,就可以通過目前頁碼來确定首頁,上一頁和下一頁以及末頁的頁碼。注意:在設定分頁時,需要将對應的頁碼作為請求參數pageindex的值進行傳遞。index.jsp頁面生成分頁操作連接配接的代碼如下:
<%
int totalPages = pageObj.getTotalPageCount(); //總頁數
int pageIndex = pageObj.getCurrPageNo(); //目前頁碼
%>
.......//省略其他
<p align="center"> 目前頁數:[<%=pageIndex%>/<%=totalPages%>]
<a href=".....&pageIndex=1">首頁</a>
<a href="........&pageIndex=<%=pageIndex-1%>">上一頁</a>
<%}
if (pageIndex < totalPages) {//控制頁面顯示風格
%>
<a href=".........&pageIndex=<%=pageIndex+1%>">下一頁</a>
<a href="...........&pageIndex=<%=totalPages%>">末頁</a>
<%}%></p>
在這種情況下如果目前頁已經是第一頁或者是最後一頁,name當使用者單擊上一頁或者下一頁時,頁面該如何顯示?顯然,目前頁碼不能小于第一頁,而下一頁不能大于最末頁,是以還要進行控制。
(3) 首頁與末頁的控制。首頁與末頁控制的原理很簡單,當在JSP擷取pageIndex變量時,首先将其與首頁和末頁進行比較判斷。如果pageIndex變量的值小于1,則将值修改為1。如果pageIndex變量的值大于末頁(即總頁數),則值修改為末頁頁碼。進而避免頁碼出現-1或者大于總頁數的情況,代碼如下。
<p align="center"> 目前頁數:[<%=pageIndex%>/<%=totalPages%>]
<%
if (pageIndex > 1) { //控制頁面顯示風格
%>
<a href="........&pageIndex=1">首頁</a>
<a href="........&pageIndex=<%=pageIndex-1%>">上一頁</a>
<%}
if (pageIndex < totalPages) {//控制頁面顯示風格
%>
<a href="........&pageIndex=<%=pageIndex+1%>">下一頁</a>
<a href=".........&pageIndex=<%=totalPages%>">末頁</a>
<%}%></p>