[TOC]
> 分頁單獨拿出來講解
# 步驟 1 : 效果
如圖所示,每頁顯示5條數據
注: 沒有分類圖片是正常的,在接下來的知識點就會做增加圖片功能了

# 步驟 2 : Page.java
新增Page這個類專門為分頁提供必要信息
屬性:
`int start; `開始位置
`int count;` 每頁顯示的數量
`int total; `總共有多少條數據
`String param;` 參數(這個屬性在后續有用到,但是分類的分頁查詢里并沒有用到,請忽略)
方法:
`getTotalPage` 根據 每頁顯示的數量count以及總共有多少條數據total,計算出總共有多少頁
`getLast `計算出最后一頁的數值是多少
`isHasPreviouse` 判斷是否有前一頁
`isHasNext` 判斷是否有后一頁
```
package com.dodoke.util;
public class Page {
private int start;
private int count;
private int total;
private String param;
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public Page(int start, int count) {
super();
this.start = start;
this.count = count;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
public boolean isHasPreviouse() {
if (start == 0)
return false;
return true;
}
public boolean isHasNext() {
if (start == getLast())
return false;
return true;
}
public int getTotalPage() {
int totalPage;
// 假設總數是50,是能夠被5整除的,那么就有10頁
if (0 == total % count)
totalPage = total / count;
// 假設總數是51,不能夠被5整除的,那么就有11頁
else
totalPage = total / count + 1;
if (0 == totalPage)
totalPage = 1;
return totalPage;
}
public int getLast() {
int last;
// 假設總數是50,是能夠被5整除的,那么最后一頁的開始就是45
if (0 == total % count)
last = total - count;
// 假設總數是51,不能夠被5整除的,那么最后一頁的開始就是50
else
last = total - total % count;
last = last < 0 ? 0 : last;
return last;
}
}
```
# 步驟 3 : 獲取分頁參數
獲取分頁信息是在BaseBackServlet的service方法中
```
int start = 0;
int count = 5;
String startTmp = request.getParameter("page.start");
String countTmp = request.getParameter("page.count");
if (null != startTmp) {
start = Integer.parseInt(startTmp);
}
if (null != countTmp) {
count = Integer.parseInt(countTmp);
}
Page page = new Page(start, count);
```
獲取網頁上傳遞來的開始位置,以及每頁需要顯示的數量
如果傳遞數據過來,開始位置取0,每頁顯示的數量取默認值:5.
```
package com.dodoke.controller;
import java.lang.reflect.Method;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.dodoke.dao.impl.CategoryDaoImpl;
import com.dodoke.dao.inter.CategoryDao;
import com.dodoke.util.Page;
/**
* Servlet implementation class BaseBackServlet
*/
@WebServlet("/BaseBackServlet")
public abstract class BaseBackServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public abstract String add(HttpServletRequest request, HttpServletResponse response);
public abstract String delete(HttpServletRequest request, HttpServletResponse response);
public abstract String edit(HttpServletRequest request, HttpServletResponse response);
public abstract String update(HttpServletRequest request, HttpServletResponse response);
public abstract String list(HttpServletRequest request, HttpServletResponse response, Page page);
public CategoryDao categoryDao = new CategoryDaoImpl();
public void service(HttpServletRequest request, HttpServletResponse response) {
int start = 0;
int count = 5;
String startTmp = request.getParameter("page.start");
String countTmp = request.getParameter("page.count");
if (null != startTmp) {
start = Integer.parseInt(startTmp);
}
if (null != countTmp) {
count = Integer.parseInt(countTmp);
}
Page page = new Page(start, count);
try {
/* 借助反射,調用對應的方法 */
String method = (String) request.getAttribute("method");
Method m;
String redirect;
if ("list".equals(method)) {
m = this.getClass().getMethod(method, javax.servlet.http.HttpServletRequest.class,
javax.servlet.http.HttpServletResponse.class,Page.class);
redirect = m.invoke(this, request, response, page).toString();
} else {
m = this.getClass().getMethod(method, javax.servlet.http.HttpServletRequest.class,
javax.servlet.http.HttpServletResponse.class);
redirect = m.invoke(this, request, response).toString();
}
/* 根據方法的返回值,進行相應的客戶端跳轉,服務端跳轉,或者僅僅是輸出字符串 */
System.out.println(redirect);
if (redirect.startsWith("@")) {
response.sendRedirect(redirect.substring(1));
} else if (redirect.startsWith("%")) {
response.getWriter().print(redirect.substring(1));
} else {
request.getRequestDispatcher(redirect).forward(request, response);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
```
# 步驟 4 : 基于分頁參數,獲取數據
接著就通過反射,訪問了CategoryServlet的list()方法,并在其中通過categoryDAO,基于page的start,和count值,獲取分頁數據。
```
List<Category> cs = categoryDao.list(page.getStart(),page.getCount());
```
# 步驟 5 : 為page對象設置總數
除此之外,還為page對象添加了總數
```
int total = categoryDao.getTotal();
page.setTotal(total);
```
為什么要加這個總數? 因為在分頁顯示的時候,要依據這個總數來判斷一共有多少頁面,最后一頁是多少。
接著通過
```
request.setAttribute("page", page);
```
把page對象,傳參到了listCategory.jsp頁面
# 步驟 6 : 為了便于理解,先來一個簡化了的adminPage.jsp
在listCategory.jsp頁面包含了分頁專用jsp:adminPage.jsp
在其中,依據page對象,進行分頁超鏈元素的顯示
完整版的adminPage.jsp 比較復雜,為了便于大家理解,我先把完整版的adminPage.jsp簡化一下
首先,分頁超鏈的效果,用的Bootstrap的分頁效果來制作
首頁超鏈:
```
<li>
<a href="?page.start=0" aria-label="Previous" >
<span aria-hidden="true">?</span>
</a>
</li>
```
上一頁超鏈:
```
<li >
<a href="?page.start=${page.start-page.count}" aria-label="Previous" >
<span aria-hidden="true">?</span>
</a>
</li>
```
下一頁超鏈:
```
<li >
<a href="?page.start=${page.start+page.count}" aria-label="Next">
<span aria-hidden="true">?</span>
</a>
</li>
```
最后一頁
```
<li >
<a href="?page.start=${page.last}" aria-label="Next">
<span aria-hidden="true">?</span>
</a>
</li>
```
中間頁
```
<c:forEach begin="0" end="${page.totalPage-1}" varStatus="status">
<li>
<a href="?page.start=${status.index*page.count}" class="current">${status.count}</a>
</li>
</c:forEach>
```
```
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<script>
$(function(){
$("ul.pagination li.disabled a").click(function(){
return false;
});
});
</script>
<nav>
<ul class="pagination">
<li>
<a href="?page.start=0" aria-label="Previous" >
<span aria-hidden="true">?</span>
</a>
</li>
<li >
<a href="?page.start=${page.start-page.count}" aria-label="Previous" >
<span aria-hidden="true">?</span>
</a>
</li>
<c:forEach begin="0" end="${page.totalPage-1}" varStatus="status">
<li>
<a href="?page.start=${status.index*page.count}" class="current">${status.count}</a>
</li>
</c:forEach>
<li >
<a href="?page.start=${page.start+page.count}" aria-label="Next">
<span aria-hidden="true">?</span>
</a>
</li>
<li >
<a href="?page.start=${page.last}" aria-label="Next">
<span aria-hidden="true">?</span>
</a>
</li>
</ul>
</nav>
```
# 步驟 7 : 完整版的adminPage.jsp
簡化的adminPage.jsp 用于幫助大家理解,其存在的問題是,即便是沒有下一頁的數據了,下一頁超鏈也可以點擊,點出來的頁面是空白的。(首頁,上一頁,下一頁和最后一頁都存在這個問題)
那么所謂的完整版的adminPage.jsp,就是對這些邊界進行了處理。當沒有下一頁的時候,對應超鏈處于不可點擊狀態。
比如首頁:
當page.hasPreviouse為false的時候,為首頁連接套用Bootstrap樣式 disabled
```
<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
<a href="?page.start=0${page.param}" aria-label="Previous" >
<span aria-hidden="true">«</span>
</a>
</li>
```

```
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<script>
$(function(){
$("ul.pagination li.disabled a").click(function(){
return false;
});
});
</script>
<nav>
<ul class="pagination">
<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
<a href="?page.start=0${page.param}" aria-label="Previous" >
<span aria-hidden="true">?</span>
</a>
</li>
<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
<a href="?page.start=${page.start-page.count}${page.param}" aria-label="Previous" >
<span aria-hidden="true">?</span>
</a>
</li>
<c:forEach begin="0" end="${page.totalPage-1}" varStatus="status">
<c:if test="${status.count*page.count-page.start<=20 && status.count*page.count-page.start>=-10}">
<li <c:if test="${status.index*page.count==page.start}">class="disabled"</c:if>>
<a
href="?page.start=${status.index*page.count}${page.param}"
<c:if test="${status.index*page.count==page.start}">class="current"</c:if>
>${status.count}</a>
</li>
</c:if>
</c:forEach>
<li <c:if test="${!page.hasNext}">class="disabled"</c:if>>
<a href="?page.start=${page.start+page.count}${page.param}" aria-label="Next">
<span aria-hidden="true">?</span>
</a>
</li>
<li <c:if test="${!page.hasNext}">class="disabled"</c:if>>
<a href="?page.start=${page.last}${page.param}" aria-label="Next">
<span aria-hidden="true">?</span>
</a>
</li>
</ul>
</nav>
```
- 項目簡介
- 功能一覽
- 前臺
- 后臺
- 開發流程
- 需求分析-展示
- 首頁
- 產品頁
- 分類頁
- 搜索結果頁
- 購物車查看頁
- 結算頁
- 確認支付頁
- 支付成功頁
- 我的訂單頁
- 確認收貨頁
- 評價頁
- 頁頭信息展示
- 需求分析-交互
- 分類頁排序
- 立即購買
- 加入購物車
- 調整訂單項數量
- 刪除訂單項
- 生成訂單
- 訂單頁功能
- 確認付款
- 確認收貨
- 提交評價信息
- 登錄
- 注冊
- 退出
- 搜索
- 前臺需求列表
- 需求分析后臺
- 分類管理
- 屬性管理
- 產品管理
- 產品圖片管理
- 產品屬性設置
- 用戶管理
- 訂單管理
- 后臺需求列表
- 表結構設計
- 數據建模
- 表與表之間的關系
- 實體類設計
- DAO類設計
- 工具類
- CategoryDao設計
- Service業務類設計
- 后臺-分類管理
- 可運行的項目
- 靜態資源
- FILTER配合SERVLET
- JSP包含關系
- 查詢
- 分頁
- 增加
- 刪除
- 編輯
- 修改
- 后臺其他管理
- 屬性管理
- 產品管理
- 產品圖片管理
- 產品屬性值設置
- 用戶管理
- 訂單管理