JavaWeb學習-案例練習-圖書管理後臺- 9 -分頁操作
凱哥java 凱哥java
前面一篇完成了多條件的查詢,這篇開始學習分頁,很多網頁是默認顯示20條數據,想看更多數據,就通過點擊下一頁的方式實現。這篇就來模擬這個分頁實現過程。
- 項目環境準備
之前我們實現的都是圖書管理後臺功能,現在分頁,我們在前端頁面,所以我把素材中product_list.jsp和ad文件夾拷貝到Eclipse中的WebContent的目錄下。product_list.jsp就是我們要實現分頁的前端頁面。
上圖是項目工程結構,全部代碼放在了github上。
https://github.com/Anthonyliu86/BookManagement_JavawebDemo - 分頁思路分析
當前product_list的效果是這樣,佈局是採用表格佈局,一行顯示四本書,也就是一個tr裏面有4個td。
爲了我們簡單,這裏我們只用一行,每行顯示4本書,想看第五本書,必須點擊下一頁菜單。所以,我們在product_list.jsp中這個表格,只留下一個tr,第一行也只留下一個td,也就是一本書,最後效果是這樣的
下圖是所有層交互的思路。
- 分頁代碼實現過程
在點擊下一頁之後,這個動作需要跳轉到一個servlet,我們先來創建這個servlet,叫pageServlet。
3.1 創建一個PageServlet.java
當前這個servlet代碼是空,這個文件主要寫設置每頁顯示個數,和當前頁id獲取,然後返回一個頁面對象。所以,我們先創建一個關於頁面的Bean類。
3.2 創建PageBean.java
在domian包下創建一個PageBean.java文件,寫入下面代碼。
import java.util.List;
public class PageBean {
private int pageSize;
private int currentPage;
private int count;
private int totalPage;
private List<Book> books;
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
3.3 Dao層代碼
在BookDao這個接口中新增兩個方法,一個是求總記錄數,第二個是查找分頁數據
/**
* 得到總記錄數
* @return
* @throws SQLException
*/
public int count() throws SQLException;
/**
* 查找分頁數據
* @param currentPage
* @param pageSize
* @return
* @throws SQLException
*/
public List<Book> findBooks(int currentPage, int pageSize)throws SQLException;
然後在BookDaoImpl.java添加這兩個方法的具體實現代碼。
public int count() throws SQLException {
QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
long l = (Long)qr.query("select count(*) from book", new ScalarHandler(1));
return (int)l;
}
public List<Book> findBooks(int currentPage, int pageSize) throws SQLException {
QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
return qr.query("select * from book limit ?,?", new BeanListHandler<Book>(Book.class),(currentPage-1)*pageSize, pageSize);
}
3.4 Service層
BookService接口添加根據currentPage和pageSize兩個參數,得到PageBean的方法。
/**
* 得到總記錄數
* @return
* @throws SQLException
*/
public int count() throws SQLException;
/**
* 查找分頁數據
* @param currentPage
* @param pageSize
* @return
* @throws SQLException
*/
public List<Book> findBooks(int currentPage, int pageSize)throws SQLException;
具體方法實現,添加到BookServiceImpl.java中
public PageBean findBooksPage(int currentPage, int pageSize) {
try {
int count = bd.count();
int totalPage = (int)Math.ceil(count*1.0/pageSize);
List<Book> books = bd.findBooks(currentPage, pageSize);
//封裝成一個PageBean對象
PageBean pb = new PageBean();
pb.setBooks(books);
pb.setCount(count);
pb.setCurrentPage(currentPage);
pb.setTotalPage(totalPage);
pb.setPageSize(pageSize);
return pb;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
3.5 Servlet代碼
回到PageServlet.java中,看看這個servlet如何寫。
package com.anthony.web.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.anthony.domain.PageBean;
import com.anthony.service.BookService;
import com.anthony.service.BookServiceImpl;
public class PageServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//初始化每頁顯示記錄數
int pageSize = 4;
int currentPage = 1; //表示當前頁
String currPage = request.getParameter("currentPage");
if(currPage != null) { //第一次訪問頁面currPage可能爲null
currentPage = Integer.parseInt(currPage);
}
//調用業務層方法
BookService bs = new BookServiceImpl();
//分頁查詢,並返回PageBean對象
PageBean pb = bs.findBooksPage(currentPage, pageSize);
//請求跳轉
request.setAttribute("pb", pb);
request.getRequestDispatcher("/product_list.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
3.6 Product_list.jsp修改
3.6.1 添加JSTL約束
在product_list.jsp頂部添加JSTL約束。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
3.6.2 解析PageBean對象到jsp中
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>bookStore列表</title>
<%--導入css --%>
<link rel="stylesheet" href="css/main.css" type="text/css" />
</head>
<body class="main">
<jsp:include page="head.jsp" />
<jsp:include page="menu_search.jsp" />
<div id="divpagecontent">
<table width="100%" border="0" cellspacing="0">
<tr>
<td>
<div style="text-align:right; margin:5px 10px 5px 0px">
<a href="index.jsp">首頁</a> > 計算機 > 圖書列表
</div>
<table cellspacing="0" class="listcontent">
<tr>
<td>
<h1>商品目錄</h1>
<hr />
<h1>計算機</h1> 共100種商品
<hr />
<div style="margin-top:20px; margin-bottom:5px">
<img src="images/productlist.gif" width="100%" height="38" />
</div>
<table cellspacing="0" class="booklist">
<tr>
<c:forEach items="${pb.books}" var="b">
<td>
<div class="divbookpic">
<p>
<a href="#"><img src="" width="115" height="129"
border="0" /> </a>
</p>
</div>
<div class="divlisttitle">
<a href="#">書名:${b.name}<br />售價:${b.price} </a>
</div></td>
<td>
</c:forEach>
</table>
<div class="pagination">
<ul>
<li class="disablepage"><<上一頁</li>
<li>第1頁/共5頁</li>
<li class="nextPage"><a href="#"><<下一頁</a></li>
</ul>
</div></td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<jsp:include page="foot.jsp" />
</body>
</html>
瀏覽器打開https://localhost:8080/BookManagement/pageServlet 效果是這樣的
3.6.3 實現上一頁和下一頁功能
現在我們就差上一頁和下一頁這個功能沒有實現。
下面代碼主要看 上一頁 和下一頁中代碼。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>bookStore列表</title>
<%--導入css --%>
<link rel="stylesheet" href="css/main.css" type="text/css" />
</head>
<body class="main">
<jsp:include page="head.jsp" />
<jsp:include page="menu_search.jsp" />
<div id="divpagecontent">
<table width="100%" border="0" cellspacing="0">
<tr>
<td>
<div style="text-align:right; margin:5px 10px 5px 0px">
<a href="index.jsp">首頁</a> > 計算機 > 圖書列表
</div>
<table cellspacing="0" class="listcontent">
<tr>
<td>
<h1>商品目錄</h1>
<hr />
<h1>計算機</h1> 共100種商品
<hr />
<div style="margin-top:20px; margin-bottom:5px">
<img src="images/productlist.gif" width="100%" height="38" />
</div>
<table cellspacing="0" class="booklist">
<tr>
<c:forEach items="${pb.books}" var="b">
<td>
<div class="divbookpic">
<p>
<a href="#"><img src="" width="115" height="129"
border="0" /> </a>
</p>
</div>
<div class="divlisttitle">
<a href="#">書名:${b.name}<br />售價:${b.price} </a>
</div>
</td>
</c:forEach>
</table>
<div class="pagination">
<ul>
<li class="disablepage"><a href="${pageContext.request.contextPath }/pageServlet?currentPage=${pb.currentPage-1}"><<上一頁</a></li>
<li>第${pb.currentPage}頁/共${pb.totalPage}頁</li>
<li class="nextPage"><a href="${pageContext.request.contextPath }/pageServlet?currentPage=${pb.currentPage+1}"><<下一頁</a></li>
</ul>
</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<jsp:include page="foot.jsp" />
</body>
</html>
效果如下
當前還是有一個問題,上一頁和下一頁都可以一直點擊下去,沒有做邊界處理。
3.6.4 上一頁和下一頁邊界處理
因爲需要對上一頁和下一頁的邊界判斷,例如上一頁邊界情況,如果當前currentPage等於1,那麼就上一頁不能再減1。同樣,當前currentPage等於totalPage,那麼不能加1. 這種if判斷,我們可以用三元運算符來一行代碼搞定。
如果currentPage=1, 前端點擊上一頁,永遠傳遞currentPage=1, 如果currentPage=totalPage,那麼傳遞就是currentPage=totalPage,也就是最後一頁。
<div class="pagination">
<ul>
<li class="disablepage"><a href="${pageContext.request.contextPath }/pageServlet?currentPage=${pb.currentPage==1? pb.currentPage:pb.currentPage-1}"><<上一頁</a></li>
<li>第${pb.currentPage}頁/共${pb.totalPage}頁</li>
<li class="nextPage"><a href="${pageContext.request.contextPath }/pageServlet?currentPage=${pb.currentPage==pb.totalPage? pb.currentPage:pb.currentPage+1}"><<下一頁</a></li>
</ul>
</div>
到這裏,分頁操作完成。