书城项目-第五阶段:图书分页的分析、书城项目-分页模型Page对象的创建、书城项目-分页初步实现、书城项目-首页、上一页、下一页、末页的实现、书城项目-跳到指定页码功能的实现、书城项目-数据有效边境检查、书城项目-分页条页码的输出、书城项目-修改分页对原来,添加、删除、修改的影响、书城项目-前台分页的初步实现、书城项目-分页条的抽取、书城项目-价格区间搜索并分页的分析、书城项目-价格区间搜索并分页功能的实现、书城项目-搜索价格区间的回显、书城项目-解决分页条中不带价格区间的bug
项目第五阶段-图书分页
2、图书分页
1)分页模块的分析
2)分页模型 Page 的抽取(当前页数,总页数,总记录数,当前页数据,每页记录数)
package top.qaqaq.pojo;
import java.util.List;
/**
* @author RichieZhang
* @create 2022-12-11 下午 1:14
*/
/**
* Page是分页的模型对象
* @param <T> 是具体的模块的javaBean类
*/
public class Page <T> {
public static final Integer PAGE_SIZE = 4;
// 当前页码
private Integer pageNo;
// 总页码
private Integer pageTotal;
// 当前页显示数量
private Integer pageSize = PAGE_SIZE;
// 总记录数
private Integer pageTotalCount;
// 当前页数据
private List<T> itmes;
// 分页条的请求地址
private String url;
public Page() {
}
public Page(Integer pageNo, Integer pageTotal, Integer pageSize, Integer pageTotalCount, List<T> itmes, String url) {
this.pageNo = pageNo;
this.pageTotal = pageTotal;
this.pageSize = pageSize;
this.pageTotalCount = pageTotalCount;
this.itmes = itmes;
this.url = url;
}
public Integer getPageNo() {
return pageNo;
}
public void setPageNo(Integer pageNo) {
this.pageNo = pageNo;
}
public Integer getPageTotal() {
return pageTotal;
}
public void setPageTotal(Integer pageTotal) {
this.pageTotal = pageTotal;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getPageTotalCount() {
return pageTotalCount;
}
public void setPageTotalCount(Integer pageTotalCount) {
this.pageTotalCount = pageTotalCount;
}
public List<T> getItmes() {
return itmes;
}
public void setItmes(List<T> itmes) {
this.itmes = itmes;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return "Page{" +
"pageNo=" + pageNo +
", pageTotal=" + pageTotal +
", pageSize=" + pageSize +
", pageTotalCount=" + pageTotalCount +
", itmes=" + itmes +
", url='" + url + '\'' +
'}';
}
}
3)分页的初步实现
BookDao 代码:
package top.qaqaq.dao;
import top.qaqaq.pojo.Book;
import java.util.List;
/**
* @author RichieZhang
* @create 2022-12-10 下午 5:36
*/
public interface BookDao {
/**
* 添加图书
* @param book
* @return
*/
public int addBook(Book book);
/**
* 根据图书id删除图书
* @param id
* @return
*/
public int deleteBookById(Integer id);
/**
* 根据图书id更新图书
* @param book
* @return
*/
public int updateBook(Book book);
/**
* 根据图书id查询图书
* @param id
* @return
*/
public Book queryBookById(Integer id);
/**
* 查询全部图书
* @return
*/
public List<Book> queryBooks();
/**
* 查询总记录数
* @return
*/
Integer queryForPageTotalCount();
/**
* 遍历当前页数据
* @param begin
* @param pageSize
* @return
*/
List<Book> queryForPageItems(int begin, int pageSize);
/**
* 按价格区间查询总记录数
* @param min
* @param max
* @return
*/
Integer queryForPageTotalCountByPrice(int min, int max);
/**
* 按价格区间遍历当前页数据
* @param begin
* @param pageSize
* @param min
* @param max
* @return
*/
List<Book> queryForPageItemsByPrice(int begin, int pageSize, int min, int max);
}
package top.qaqaq.dao.impl;
import top.qaqaq.dao.BookDao;
import top.qaqaq.pojo.Book;
import java.util.List;
/**
* @author RichieZhang
* @create 2022-12-10 下午 5:40
*/
public class BookDaoImpl extends BaseDao implements BookDao {
@Override
public int addBook(Book book) {
String sql = "insert into t_book(name,author,price,sales,stock,img_path) values(?,?,?,?,?,?)";
return update(sql, book.getName(), book.getAuthor(), book.getPrice(), book.getSales(), book.getStock(), book.getImgpath());
}
@Override
public int deleteBookById(Integer id) {
String sql = "delete from t_book where id = ?";
return update(sql, id);
}
@Override
public int updateBook(Book book) {
String sql = "update t_book set name=?,author=?,price=?,sales=?,stock=?,img_path=? where id = ?";
return update(sql, book.getName(), book.getAuthor(), book.getPrice(), book.getSales(), book.getStock(), book.getImgpath(), book.getId());
}
@Override
public Book queryBookById(Integer id) {
String sql = "select id,name,author,price,sales,stock,img_path imgpath from t_book where id = ?";
return queryForOne(Book.class, sql, id);
}
@Override
public List<Book> queryBooks() {
String sql = "select id,name,author,price,sales,stock,img_path imgpath from t_book";
return queryForList(Book.class, sql);
}
@Override
public Integer queryForPageTotalCount() {
String sql = "select count(*) from t_book";
Number count = (Number) queryForSingleValue(sql);
return count.intValue();
}
@Override
public List<Book> queryForPageItems(int begin, int pageSize) {
String sql = "select id,name,author,price,sales,stock,img_path imgpath from t_book limit ?,?";
return queryForList(Book.class,sql,begin,pageSize);
}
@Override
public Integer queryForPageTotalCountByPrice(int min, int max) {
String sql = "select count(*) from t_book where price between ? and ?";
Number count = (Number) queryForSingleValue(sql,min,max);
return count.intValue();
}
@Override
public List<Book> queryForPageItemsByPrice(int begin, int pageSize, int min, int max) {
String sql = "select id,name,author,price,sales,stock,img_path imgpath " +
"from t_book where price between ? and ? order by price limit ?,?";
return queryForList(Book.class,sql,min,max,begin,pageSize);
}
}
BookService 代码:
package top.qaqaq.service;
import top.qaqaq.pojo.Book;
import top.qaqaq.pojo.Page;
import java.util.List;
/**
* @author RichieZhang
* @create 2022-12-10 下午 7:37
*/
public interface BookService {
/**
* 添加图书
* @param book
*/
public void addBook(Book book);
/**
* 根据图书id删除图书
* @param id
*/
public void deleteBookById(Integer id);
/**
* 根据图书id更新图书
* @param book
*/
public void updateBook(Book book);
/**
* 根据图书id查询图书
* @param id
* @return
*/
public Book queryBookById(Integer id);
/**
* 查询全部图书
* @return
*/
public List<Book> queryBooks();
/**
* 图书分页
* @param pageNo
* @param pageSize
* @return
*/
Page<Book> page(int pageNo, int pageSize);
/**
* 按价格查找 图书分页
* @param pageNo
* @param pageSize
* @param min
* @param max
* @return
*/
Page<Book> pageByPrice(int pageNo, int pageSize, int min, int max);
}
package top.qaqaq.service.impl;
import top.qaqaq.dao.BookDao;
import top.qaqaq.dao.impl.BookDaoImpl;
import top.qaqaq.pojo.Book;
import top.qaqaq.pojo.Page;
import top.qaqaq.service.BookService;
import java.util.List;
/**
* @author RichieZhang
* @create 2022-12-10 下午 7:42
*/
public class BookServiceImpl implements BookService {
private BookDao bookDao = new BookDaoImpl();
@Override
public void addBook(Book book) {
bookDao.addBook(book);
}
@Override
public void deleteBookById(Integer id) {
bookDao.deleteBookById(id);
}
@Override
public void updateBook(Book book) {
bookDao.updateBook(book);
}
@Override
public Book queryBookById(Integer id) {
return bookDao.queryBookById(id);
}
@Override
public List<Book> queryBooks() {
return bookDao.queryBooks();
}
@Override
public Page<Book> page(int pageNo, int pageSize) {
Page<Book> page = new Page<Book>();
// 设置每页显示的数量
page.setPageSize(pageSize);
// 求总记录数
Integer pageTotalCount = bookDao.queryForPageTotalCount();
// 设置总记录数
page.setPageTotalCount(pageTotalCount);
// 求总页码
Integer pageTotal = pageTotalCount / pageSize;
if (pageTotalCount % pageSize > 0){
pageTotal += 1;
}
// 设置总页码
page.setPageTotal(pageTotal);
// 设置当前页码
page.setPageNo(pageNo);
// 求当前页数据的开始索引
int begin = (page.getPageNo() - 1) * pageSize;
// 求当前页数据
List<Book> items = bookDao.queryForPageItems(begin,pageSize);
// 设置当前页数据
page.setItmes(items);
return page;
}
@Override
public Page<Book> pageByPrice(int pageNo, int pageSize, int min, int max) {
Page<Book> page = new Page<Book>();
// 设置每页显示的数量
page.setPageSize(pageSize);
// 求总记录数
Integer pageTotalCount = bookDao.queryForPageTotalCountByPrice(min, max);
// 设置总记录数
page.setPageTotalCount(pageTotalCount);
// 求总页码
Integer pageTotal = pageTotalCount / pageSize;
if (pageTotalCount % pageSize > 0){
pageTotal += 1;
}
// 设置总页码
page.setPageTotal(pageTotal);
// 设置当前页码
page.setPageNo(pageNo);
// 求当前页数据的开始索引
int begin = (page.getPageNo() - 1) * pageSize;
// 求当前页数据
List<Book> items = bookDao.queryForPageItemsByPrice(begin,pageSize,min,max);
// 设置当前页数据
page.setItmes(items);
return page;
}
}
BookServlet 程序的代码:
package top.qaqaq.web;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import top.qaqaq.pojo.Book;
import top.qaqaq.pojo.Page;
import top.qaqaq.service.BookService;
import top.qaqaq.service.impl.BookServiceImpl;
import top.qaqaq.utils.WebUtils;
import java.io.IOException;
import java.util.List;
/**
* @author RichieZhang
* @create 2022-12-10 下午 7:51
*/
public class BookServlet extends BaseServlet {
private BookService bookService = new BookServiceImpl();
/**
* 处理分页功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取请求的参数 pageNo 和 pageSize
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"),1);
int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);
// 2. 调用BookService.page(pageNo,PageSize):Page对象
Page<Book> page = bookService.page(pageNo,pageSize);
page.setUrl("manager/bookServlet?action=page");
// 3. 保存Page对象到Request域中
req.setAttribute("page",page);
// 4. 请求转发到/pages/manager/book_manager.jsp页面
req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);
}
/**
* 负责添加图书
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req, resp);
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"),0);
pageNo += 1;
// 1. 获取请求的参数==封装成为Book对象
Book book = WebUtils.copyParamToBean(req.getParameterMap(), new Book());
// 2. 调用BookService.addBook()保存图书
bookService.addBook(book);
// 3. 跳到图书列表页面
// /manager/bookServlet?action=list
// 如果使用请求转发,则为一次请求,刷新会重复提交数据
// req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req,resp);
// 所以使用请求重定向
resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=page&pageNo=" + pageNo);
}
/**
* 负责删除图书
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req, resp);
// 1. 获取请求的参数id,图书编程
int id = WebUtils.parseInt(req.getParameter("id"),0);
// 2. 调用bookService.deleteBookById();删除图书
bookService.deleteBookById(id);
// 3. 重定向回图书列表管理页面
// /book/manager/bookServlet?action=list
resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=page&pageNo=" + req.getParameter("pageNo"));
}
/**
* 保存修改图书的操作
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req, resp);
// 1. 获取请求的参数==封装成为Book对象
Book book = WebUtils.copyParamToBean(req.getParameterMap(), new Book());
// 2. 调用BookService.updateBook( book );修改图书
bookService.updateBook(book);
// 3. 重定向回图书列表管理页面
// 地址:/工程名/manager/bookServlet?action=list
resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=page&pageNo=" + req.getParameter("pageNo"));
}
/**
* 获取要修改的图书信息
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void getBook(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req, resp);
// 1. 获取请求的参数图书编号
int id = WebUtils.parseInt(req.getParameter("id"),0);
// 2. 调用bookService.queryBookById查询图书
Book book = bookService.queryBookById(id);
// 3. 保存图书到Request域中
req.setAttribute("book",book);
// 4. 请求转发到。pages/manager/book_edit.jsp页面
req.getRequestDispatcher("/pages/manager/book_edit.jsp").forward(req,resp);
}
/**
* 负责遍历图书
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req, resp);
// 1. 通过BookService查询全部图书
List<Book> books = bookService.queryBooks();
// 2. 把全部图书保存到Request域中
req.setAttribute("books", books);
// 3. 请求转发到/pages/manager/book_manager.jsp页面
req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);
}
}
manager_menu.jsp 中【图书管理】请求地址的修改:
<%--
Created by IntelliJ IDEA.
User: ZRich
Date: 2022/12/9
Time: 下午 5:33
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div>
<%-- action=list表示调用BookServlet.java里的list方法 --%>
<a href="manager/bookServlet?action=page">图书管理</a>
<a href="pages/manager/order_manager.jsp">订单管理</a>
<a href="index.jsp">返回商城</a>
</div>
book_manager.jsp 修改:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图书管理</title>
<%-- 静态包含 base标签,css样式,jQuery文件 --%>
<%@ include file="/pages/common/head.jsp"%>
<script type="text/javascript">
$(function () {
// 给删除的a标签绑定单击事件,用于删除的确认提示操作
$("a.deleteClass").click(function () {
//在事件的function函数中,有一个this对象。这个this对象,是当前正在响应事件的dom对象。
/**
* confirm是确认提示框函数
* 参数是它的提示内容
* 它有两个按钮,一个确认,一个取消。
* 返回true表示点击了,确认,返回false表示点击取消
*/
return confirm("你确定要删除【" + $(this).parent().parent().find("td:first").text() + "】?")
//return false// 阻止元素的默认行为===不提交请求
})
})
</script>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="../../static/img/logo.gif" >
<span class="wel_word">图书管理系统</span>
<%-- 静态包含 manager 管理模块的菜单 --%>
<%@include file="/pages/common/manager_menu.jsp"%>
</div>
<div id="main">
<table>
<tr>
<td>名称</td>
<td>价格</td>
<td>作者</td>
<td>销量</td>
<td>库存</td>
<td colspan="2">操作</td>
</tr>
<c:forEach items="${requestScope.page.itmes}" var="book">
<tr>
<td>${book.name}</td>
<td>${book.price}</td>
<td>${book.author}</td>
<td>${book.sales}</td>
<td>${book.stock}</td>
<td><a href="manager/bookServlet?action=getBook&id=${book.id}&pageNo=${requestScope.page.pageNo}">修改</a></td>
<td><a class="deleteClass" href="manager/bookServlet?action=delete&id=${book.id}&pageNo=${requestScope.page.pageNo}">删除</a></td>
</tr>
</c:forEach>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><a href="pages/manager/book_edit.jsp?pageNo=${requestScope.page.pageTotal}">添加图书</a></td>
</tr>
</table>
<%-- 静态包含分页条 --%>
<%@include file="/pages/common/page_nav.jsp"%>
</div>
<%-- 静态包含页脚内容 --%>
<%@include file="/pages/common/footer.jsp"%>
</body>
</html>
page_nav.jsp
<%--
Created by IntelliJ IDEA.
User: ZRich
Date: 2022/12/11
Time: 下午 7:30
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 分页条的开始 --%>
<div id="page_nav">
<%-- 大于首页,才显示 --%>
<c:if test="${requestScope.page.pageNo > 1}">
<a href="${ requestScope.page.url }&pageNo=1">首页</a>
<a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageNo-1}">上一页</a>
</c:if>
<%-- 页码输出的开始 --%>
<c:choose>
<%-- 情况1:如果总页码小于等于5的情况,页码的范围是:1-总页码 --%>
<c:when test="${requestScope.page.pageTotal <= 5}">
<c:set var="begin" value="1" />
<c:set var="end" value="${requestScope.page.pageTotal}" />
</c:when>
<%-- 情况2:总页码大于5的情况。 --%>
<c:when test="${requestScope.page.pageTotal > 5}">
<c:choose>
<%--小情况 1:当前页码为前面 3 个:1,2,3 的情况,页码范围是:1-5.--%>
<c:when test="${requestScope.page.pageNo <= 3}">
<c:set var="begin" value="1" />
<c:set var="end" value="5" />
</c:when>
<%-- 小情况 2:当前页码为最后 3 个,8,9,10,页码范围是:总页码减 4 - 总页码 --%>
<c:when test="${requestScope.page.pageNo >= requestScope.page.pageTotal - 3}">
<c:set var="begin" value="${requestScope.page.pageTotal - 4}" />
<c:set var="end" value="${requestScope.page.pageTotal}" />
</c:when>
<%-- 小情况 3:4,5,6,7,页码范围是:当前页码减 2 - 当前页码加 2 --%>
<c:otherwise>
<c:set var="begin" value="${requestScope.page.pageNo - 2}" />
<c:set var="end" value="${requestScope.page.pageNo + 2}" />
</c:otherwise>
</c:choose>
</c:when>
</c:choose>
<c:forEach begin="${begin}" end="${end}" var="i">
<c:if test="${i == requestScope.page.pageNo}">
【${i}】
</c:if>
<c:if test="${i != requestScope.page.pageNo}">
<a href="${ requestScope.page.url }&pageNo=${i}">${i}</a>
</c:if>
</c:forEach>
<%-- 页码输出的结束 --%>
<%-- 如果已经 是最后一页,则不显示下一页,末页 --%>
<c:if test="${requestScope.page.pageNo < requestScope.page.pageTotal}">
<a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageNo+1}">下一页</a>
<a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageTotal}">末页</a>
</c:if>
共${requestScope.page.pageTotal}页,${requestScope.page.pageTotalCount}条记录
到第<input value="${param.pageNo}" name="pn" id="pn_input"/>页
<input id="searchPageBtn" type="button" value="确定">
<script type="text/javascript">
$(function () {
// 跳到指定的页码
$("#searchPageBtn").click(function () {
var pageNo = $("#pn_input").val();
var pageTotal = ${requestScope.page.pageTotal};
if (pageNo < 1) {
pageNo = 1;
location.href = "${pageScope.basePath}${ requestScope.page.url }&pageNo=" + pageNo;
pageNo.val(1)
}
if (pageNo > pageTotal) {
pageNo = pageTotal;
location.href = "${pageScope.basePath}${ requestScope.page.url }&pageNo=" + pageNo;
pageno.val(pageTotal)
}
// javaScript语言中提供了一个Location地址栏对象
// 它有一个属性叫href. 它可以获取浏览器地址栏中的地址
// href属性可读,可写
location.href = "${pageScope.basePath}${ requestScope.page.url }&pageNo=" + pageNo;
})
})
</script>
</div>
<%-- 分页条的结束 --%>
<div id="page_nav">
<a href="#">首页</a>
<a href="#">上一页</a>
<a href="#">3</a>
【${ requestScope.page.pageNo }】
<a href="#">5</a>
<a href="#">下一页</a>
<a href="#">末页</a>
共${ requestScope.page.pageTotal }页,${ requestScope.page.pageTotalCount }条记录
到第<input value="4" name="pn" id="pn_input"/>页
<input type="button" value="确定"></div>
4)首页、上一页、下一页、末页实现
<div id="page_nav">
<%--大于首页,才显示--%>
<c:if test="${requestScope.page.pageNo > 1}">
<a href="manager/bookServlet?action=page&pageNo=1">首页</a>
<a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageNo-1}">上一页</a></c:if>
<a href="#">3</a>
【${ requestScope.page.pageNo }】
<a href="#">5</a>
<%-- 如果已经 是最后一页,则不显示下一页,末页 --%>
<c:if test="${requestScope.page.pageNo < requestScope.page.pageTotal}">
<a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageNo+1}">下一页</a>
<a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageTotal}">末页</a></c:if>
共${ requestScope.page.pageTotal }页,${ requestScope.page.pageTotalCount }条记录
到第<input value="4" name="pn" id="pn_input"/>页
<input type="button" value="确定"></div>
5)分页模块中跳转到指定页数功能实现
<div id="page_nav">
<%--大于首页,才显示--%>
<c:if test="${requestScope.page.pageNo > 1}">
<a href="manager/bookServlet?action=page&pageNo=1">首页</a>
<a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageNo-1}">上一页</a></c:if>
<a href="#">3</a>
【${ requestScope.page.pageNo }】
<a href="#">5</a>
<%-- 如果已经 是最后一页,则不显示下一页,末页 --%>
<c:if test="${requestScope.page.pageNo < requestScope.page.pageTotal}">
<a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageNo+1}">下一页</a>
<a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageTotal}">末页</a></c:if>
共${ requestScope.page.pageTotal }页,${ requestScope.page.pageTotalCount }条记录
到第<input value="${param.pageNo}" name="pn" id="pn_input"/>页
<input id="searchPageBtn" type="button" value="确定">
<script type="text/javascript">
$(function () {
// 跳到指定的页码
$("#searchPageBtn").click(function () {
var pageNo = $("#pn_input").val();
<%--var pageTotal = ${requestScope.page.pageTotal};--%>
<%--alert(pageTotal);--%>
// javaScript 语言中提供了一个 location 地址栏对象
// 它有一个属性叫 href.它可以获取浏览器地址栏中的地址
// href 属性可读,可写
location.href = "${pageScope.basePath}manager/bookServlet?action=page&pageNo=" +
pageNo;
});
});
</script>
</div>
Page 对象中的修改:
public void setPageNo(Integer pageNo) {
/* 数据边界的有效检查 */
if (pageNo < 1) {
pageNo = 1;
}
if (pageNo > pageTotal) {
pageNo = pageTotal;
}
this.pageNo = pageNo;
}
BookService 中 page 方法的修改:
@Override
public Page<Book> page(int pageNo, int pageSize) {
Page<Book> page = new Page<Book>();
// 设置每页显示的数量
page.setPageSize(pageSize);
// 求总记录数
Integer pageTotalCount = bookDao.queryForPageTotalCount();
// 设置总记录数
page.setPageTotalCount(pageTotalCount);
// 求总页码
Integer pageTotal = pageTotalCount / pageSize;
if (pageTotalCount % pageSize > 0){
pageTotal += 1;
}
// 设置总页码
page.setPageTotal(pageTotal);
// 设置当前页码
page.setPageNo(pageNo);
// 求当前页数据的开始索引
int begin = (page.getPageNo() - 1) * pageSize;
// 求当前页数据
List<Book> items = bookDao.queryForPageItems(begin,pageSize);
// 设置当前页数据
page.setItmes(items);
return page;
}
6)分页模块中,页码 1,2,【3】,4,5 的显示,要显示 5 个页码,并且页码可以点击跳转。
需求:显示 5 个连续的页码,而且当前页码在中间。除了当前页码之外,每个页码都可以点击跳到指定页。
情况 1:如果总页码小于等于 5 的情况,页码的范围是:1-总页码
1 页 1
2 页 1,2
3 页 1,2,3
4 页 1,2,3,4
5 页 1,2,3,4,5
情况 2:总页码大于 5 的情况。假设一共 10 页
小情况 1:当前页码为前面 3 个:1,2,3 的情况,页码范围是:1-5.
【1】2,3,4,5
1【2】3,4,5
1,2【3】4,5
小情况 2:当前页码为最后 3 个,8,9,10,页码范围是:总页码减 4 – 总页码
6,7【8】9,10
6,7,8【9】10
6,7,8,9【10】
小情况 3:4,5,6,7,页码范围是:当前页码减 2 – 当前页码加 2
2,3,4,5,6
3,4,5,6,7
4,5,6,7,8
5,6,7,8,9
<%--
Created by IntelliJ IDEA.
User: ZRich
Date: 2022/12/11
Time: 下午 7:30
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 分页条的开始 --%>
<div id="page_nav">
<%-- 大于首页,才显示 --%>
<c:if test="${requestScope.page.pageNo > 1}">
<a href="${ requestScope.page.url }&pageNo=1">首页</a>
<a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageNo-1}">上一页</a>
</c:if>
<%-- 页码输出的开始 --%>
<c:choose>
<%-- 情况1:如果总页码小于等于5的情况,页码的范围是:1-总页码 --%>
<c:when test="${requestScope.page.pageTotal <= 5}">
<c:set var="begin" value="1" />
<c:set var="end" value="${requestScope.page.pageTotal}" />
</c:when>
<%-- 情况2:总页码大于5的情况。 --%>
<c:when test="${requestScope.page.pageTotal > 5}">
<c:choose>
<%--小情况 1:当前页码为前面 3 个:1,2,3 的情况,页码范围是:1-5.--%>
<c:when test="${requestScope.page.pageNo <= 3}">
<c:set var="begin" value="1" />
<c:set var="end" value="5" />
</c:when>
<%-- 小情况 2:当前页码为最后 3 个,8,9,10,页码范围是:总页码减 4 - 总页码 --%>
<c:when test="${requestScope.page.pageNo >= requestScope.page.pageTotal - 3}">
<c:set var="begin" value="${requestScope.page.pageTotal - 4}" />
<c:set var="end" value="${requestScope.page.pageTotal}" />
</c:when>
<%-- 小情况 3:4,5,6,7,页码范围是:当前页码减 2 - 当前页码加 2 --%>
<c:otherwise>
<c:set var="begin" value="${requestScope.page.pageNo - 2}" />
<c:set var="end" value="${requestScope.page.pageNo + 2}" />
</c:otherwise>
</c:choose>
</c:when>
</c:choose>
<c:forEach begin="${begin}" end="${end}" var="i">
<c:if test="${i == requestScope.page.pageNo}">
【${i}】
</c:if>
<c:if test="${i != requestScope.page.pageNo}">
<a href="${ requestScope.page.url }&pageNo=${i}">${i}</a>
</c:if>
</c:forEach>
<%-- 页码输出的结束 --%>
<%-- 如果已经 是最后一页,则不显示下一页,末页 --%>
<c:if test="${requestScope.page.pageNo < requestScope.page.pageTotal}">
<a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageNo+1}">下一页</a>
<a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageTotal}">末页</a>
</c:if>
共${requestScope.page.pageTotal}页,${requestScope.page.pageTotalCount}条记录
到第<input value="${param.pageNo}" name="pn" id="pn_input"/>页
<input id="searchPageBtn" type="button" value="确定">
<script type="text/javascript">
$(function () {
// 跳到指定的页码
$("#searchPageBtn").click(function () {
var pageNo = $("#pn_input").val();
var pageTotal = ${requestScope.page.pageTotal};
if (pageNo < 1) {
pageNo = 1;
location.href = "${pageScope.basePath}${ requestScope.page.url }&pageNo=" + pageNo;
pageNo.val(1)
}
if (pageNo > pageTotal) {
pageNo = pageTotal;
location.href = "${pageScope.basePath}${ requestScope.page.url }&pageNo=" + pageNo;
pageno.val(pageTotal)
}
// javaScript语言中提供了一个Location地址栏对象
// 它有一个属性叫href. 它可以获取浏览器地址栏中的地址
// href属性可读,可写
location.href = "${pageScope.basePath}${ requestScope.page.url }&pageNo=" + pageNo;
})
})
</script>
</div>
<%-- 分页条的结束 --%>
7) 修改分页后,增加,删除,修改图书信息的回显页面
以修改图书为示例:
1、在修改的请求地址上追加当前页码参数:
book_manager.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图书管理</title>
<%-- 静态包含 base标签,css样式,jQuery文件 --%>
<%@ include file="/pages/common/head.jsp"%>
<script type="text/javascript">
$(function () {
// 给删除的a标签绑定单击事件,用于删除的确认提示操作
$("a.deleteClass").click(function () {
//在事件的function函数中,有一个this对象。这个this对象,是当前正在响应事件的dom对象。
/**
* confirm是确认提示框函数
* 参数是它的提示内容
* 它有两个按钮,一个确认,一个取消。
* 返回true表示点击了,确认,返回false表示点击取消
*/
return confirm("你确定要删除【" + $(this).parent().parent().find("td:first").text() + "】?")
//return false// 阻止元素的默认行为===不提交请求
})
})
</script>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="../../static/img/logo.gif" >
<span class="wel_word">图书管理系统</span>
<%-- 静态包含 manager 管理模块的菜单 --%>
<%@include file="/pages/common/manager_menu.jsp"%>
</div>
<div id="main">
<table>
<tr>
<td>名称</td>
<td>价格</td>
<td>作者</td>
<td>销量</td>
<td>库存</td>
<td colspan="2">操作</td>
</tr>
<c:forEach items="${requestScope.page.itmes}" var="book">
<tr>
<td>${book.name}</td>
<td>${book.price}</td>
<td>${book.author}</td>
<td>${book.sales}</td>
<td>${book.stock}</td>
<td><a href="manager/bookServlet?action=getBook&id=${book.id}&pageNo=${requestScope.page.pageNo}">修改</a></td>
<td><a class="deleteClass" href="manager/bookServlet?action=delete&id=${book.id}&pageNo=${requestScope.page.pageNo}">删除</a></td>
</tr>
</c:forEach>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><a href="pages/manager/book_edit.jsp?pageNo=${requestScope.page.pageTotal}">添加图书</a></td>
</tr>
</table>
<%-- 静态包含分页条 --%>
<%@include file="/pages/common/page_nav.jsp"%>
</div>
<%-- 静态包含页脚内容 --%>
<%@include file="/pages/common/footer.jsp"%>
</body>
</html>
2、在 book_edit.jsp 页面中使用隐藏域记录下 pageNo 参数
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>编辑图书</title>
<%-- 静态包含 base标签,css样式,jQuery文件 --%>
<%@ include file="/pages/common/head.jsp"%>
<style type="text/css">
h1 {
text-align: center;
margin-top: 200px;
}
h1 a {
color:red;
}
input {
text-align: center;
}
</style>
</head>
<body>
<!--
遇到的问题:
book_edit.jsp页面,既要做添加操作。又要做修改操作,而到底是添加,还是修改是由一个隐藏域来决定的。
如何动态修改隐藏域<input type="hidden" name="action" value="xxx" /> 让它的值既可以实现添加,又可以实现修改操作?
//方案一:
可以当请求发起时,附带上当前要操作的值。并注入到隐藏域中。
//方案二:
可以通过判断当前请求参数中是否包含有id参数。如果有说明是修改操作。如果没有说明是添加操作。
是否是添加操作:
<%-- ${ empty param.id ? "add" : "update"}--%>
//方案三:
可以通过判断,Request域中是否包含有修改的图书信息对象,如果没有说明是添加操作。如果有说明是修改操作。
是否是添加操作:
<%-- ${ empty requestScope.book ? "add" : "update"}--%>
-->
<div id="header">
<img class="logo_img" alt="" src="../../static/img/logo.gif" >
<span class="wel_word">编辑图书</span>
<%-- 静态包含 manager 管理模块的菜单 --%>
<%@include file="/pages/common/manager_menu.jsp"%>
</div>
<div id="main">
<form action="manager/bookServlet" method="get">
<input type="hidden" name="pageNo" value="${param.pageNo}">
<input type="hidden" name="action" value="${ empty param.id ? "add" : "update"}" />
<input type="hidden" name="id" value="${requestScope.book.id}" />
<table>
<tr>
<td>名称</td>
<td>价格</td>
<td>作者</td>
<td>销量</td>
<td>库存</td>
<td colspan="2">操作</td>
</tr>
<tr>
<td><input name="name" type="text" value="${requestScope.book.name}"/></td>
<td><input name="price" type="text" value="${requestScope.book.price}"/></td>
<td><input name="author" type="text" value="${requestScope.book.author}"/></td>
<td><input name="sales" type="text" value="${requestScope.book.sales}"/></td>
<td><input name="stock" type="text" value="${requestScope.book.stock}"/></td>
<td><input type="submit" value="提交"/></td>
</tr>
</table>
</form>
</div>
<%-- 静态包含页脚内容 --%>
<%@include file="/pages/common/footer.jsp"%>
</body>
</html>
3、在服务器重定向的时候,获取当前页码追加上进行跳转
package top.qaqaq.web;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import top.qaqaq.pojo.Book;
import top.qaqaq.pojo.Page;
import top.qaqaq.service.BookService;
import top.qaqaq.service.impl.BookServiceImpl;
import top.qaqaq.utils.WebUtils;
import java.io.IOException;
import java.util.List;
/**
* @author RichieZhang
* @create 2022-12-10 下午 7:51
*/
public class BookServlet extends BaseServlet {
private BookService bookService = new BookServiceImpl();
/**
* 处理分页功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取请求的参数 pageNo 和 pageSize
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"),1);
int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);
// 2. 调用BookService.page(pageNo,PageSize):Page对象
Page<Book> page = bookService.page(pageNo,pageSize);
page.setUrl("manager/bookServlet?action=page");
// 3. 保存Page对象到Request域中
req.setAttribute("page",page);
// 4. 请求转发到/pages/manager/book_manager.jsp页面
req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);
}
/**
* 负责添加图书
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req, resp);
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"),0);
pageNo += 1;
// 1. 获取请求的参数==封装成为Book对象
Book book = WebUtils.copyParamToBean(req.getParameterMap(), new Book());
// 2. 调用BookService.addBook()保存图书
bookService.addBook(book);
// 3. 跳到图书列表页面
// /manager/bookServlet?action=list
// 如果使用请求转发,则为一次请求,刷新会重复提交数据
// req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req,resp);
// 所以使用请求重定向
resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=page&pageNo=" + pageNo);
}
/**
* 负责删除图书
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req, resp);
// 1. 获取请求的参数id,图书编程
int id = WebUtils.parseInt(req.getParameter("id"),0);
// 2. 调用bookService.deleteBookById();删除图书
bookService.deleteBookById(id);
// 3. 重定向回图书列表管理页面
// /book/manager/bookServlet?action=list
resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=page&pageNo=" + req.getParameter("pageNo"));
}
/**
* 保存修改图书的操作
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req, resp);
// 1. 获取请求的参数==封装成为Book对象
Book book = WebUtils.copyParamToBean(req.getParameterMap(), new Book());
// 2. 调用BookService.updateBook( book );修改图书
bookService.updateBook(book);
// 3. 重定向回图书列表管理页面
// 地址:/工程名/manager/bookServlet?action=list
resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=page&pageNo=" + req.getParameter("pageNo"));
}
/**
* 获取要修改的图书信息
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void getBook(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req, resp);
// 1. 获取请求的参数图书编号
int id = WebUtils.parseInt(req.getParameter("id"),0);
// 2. 调用bookService.queryBookById查询图书
Book book = bookService.queryBookById(id);
// 3. 保存图书到Request域中
req.setAttribute("book",book);
// 4. 请求转发到。pages/manager/book_edit.jsp页面
req.getRequestDispatcher("/pages/manager/book_edit.jsp").forward(req,resp);
}
/**
* 负责遍历图书
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req, resp);
// 1. 通过BookService查询全部图书
List<Book> books = bookService.queryBooks();
// 2. 把全部图书保存到Request域中
req.setAttribute("books", books);
// 3. 请求转发到/pages/manager/book_manager.jsp页面
req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);
}
}
3、首页 index.jsp 的跳转
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 只负责请求转发 --%>
<jsp:forward page="/client/bookServlet?action=page"></jsp:forward>
package top.qaqaq.web;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import top.qaqaq.pojo.Book;
import top.qaqaq.pojo.Page;
import top.qaqaq.service.BookService;
import top.qaqaq.service.impl.BookServiceImpl;
import top.qaqaq.utils.WebUtils;
import java.io.IOException;
/**
* @author RichieZhang
* @create 2022-12-11 下午 6:48
*/
public class ClientBookServlet extends BaseServlet{
private BookService bookService = new BookServiceImpl();
/**
* 处理分页功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取请求的参数 pageNo 和 pageSize
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"),1);
int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);
// 2. 调用BookService.page(pageNo,PageSize):Page对象
Page<Book> page = bookService.page(pageNo,pageSize);
page.setUrl("client/bookServlet?action=page");
// 3. 保存Page对象到Request域中
req.setAttribute("page",page);
// 4. 请求转发到/pages/client/index.jsp页面
req.getRequestDispatcher("/pages/client/index.jsp").forward(req,resp);
}
/**
* 处理按价格查找 分页功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void pageByPrice(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取请求的参数 pageNo 和 pageSize
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"),1);
int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);
int min = WebUtils.parseInt(req.getParameter("min"),0);
int max = WebUtils.parseInt(req.getParameter("max"), Integer.MAX_VALUE);
// 2. 调用BookService.page(pageNo,PageSize):Page对象
Page<Book> page = bookService.pageByPrice(pageNo,pageSize,min,max);
StringBuilder sb = new StringBuilder("client/bookServlet?action=pageByPrice");
// 如果有最小价格的参数,追加到分页条的地址参数中
if (req.getParameter("min") != null) {
sb.append("&min=").append(req.getParameter("min"));
}
// 如果有最大价格的参数,追加到分页条的地址参数中
if (req.getParameter("max") != null) {
sb.append("&max=").append(req.getParameter("max"));
}
page.setUrl(sb.toString());
// 3. 保存Page对象到Request域中
req.setAttribute("page",page);
// 4. 请求转发到/pages/client/index.jsp页面
req.getRequestDispatcher("/pages/client/index.jsp").forward(req,resp);
}
}
4、分页条的抽取
4.1、抽取分页条中请求地址为 url 变量
4.1.1.在 page 对象中添加 url 属性
package top.qaqaq.pojo;
import java.util.List;
/**
* @author RichieZhang
* @create 2022-12-11 下午 1:14
*/
/**
* Page是分页的模型对象
* @param <T> 是具体的模块的javaBean类
*/
public class Page <T> {
public static final Integer PAGE_SIZE = 4;
// 当前页码
private Integer pageNo;
// 总页码
private Integer pageTotal;
// 当前页显示数量
private Integer pageSize = PAGE_SIZE;
// 总记录数
private Integer pageTotalCount;
// 当前页数据
private List<T> itmes;
// 分页条的请求地址
private String url;
public Page() {
}
public Page(Integer pageNo, Integer pageTotal, Integer pageSize, Integer pageTotalCount, List<T> itmes, String url) {
/* 数据边界的有效检查 */
if (pageNo < 1) {
pageNo = 1;
}
if (pageNo > pageTotal) {
pageNo = pageTotal;
}
this.pageNo = pageNo;
this.pageTotal = pageTotal;
this.pageSize = pageSize;
this.pageTotalCount = pageTotalCount;
this.itmes = itmes;
this.url = url;
}
public Integer getPageNo() {
return pageNo;
}
public void setPageNo(Integer pageNo) {
/* 数据边界的有效检查 */
if (pageNo < 1) {
pageNo = 1;
}
if (pageNo > pageTotal) {
pageNo = pageTotal;
}
this.pageNo = pageNo;
}
public Integer getPageTotal() {
return pageTotal;
}
public void setPageTotal(Integer pageTotal) {
this.pageTotal = pageTotal;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getPageTotalCount() {
return pageTotalCount;
}
public void setPageTotalCount(Integer pageTotalCount) {
this.pageTotalCount = pageTotalCount;
}
public List<T> getItmes() {
return itmes;
}
public void setItmes(List<T> itmes) {
this.itmes = itmes;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return "Page{" +
"pageNo=" + pageNo +
", pageTotal=" + pageTotal +
", pageSize=" + pageSize +
", pageTotalCount=" + pageTotalCount +
", itmes=" + itmes +
", url='" + url + '\'' +
'}';
}
}
4.1.2 在 Servlet 程序的 page 分页方法中设置 url 的分页请求地址
/**
* 处理分页功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取请求的参数 pageNo 和 pageSize
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"),1);
int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);
// 2. 调用BookService.page(pageNo,PageSize):Page对象
Page<Book> page = bookService.page(pageNo,pageSize);
page.setUrl("client/bookServlet?action=page");
// 3. 保存Page对象到Request域中
req.setAttribute("page",page);
// 4. 请求转发到/pages/client/index.jsp页面
req.getRequestDispatcher("/pages/client/index.jsp").forward(req,resp);
}
4.1.3、修改分页条中请求地址为 url 变量输出,并抽取一个单独的 jsp 页面
<%--
Created by IntelliJ IDEA.
User: ZRich
Date: 2022/12/11
Time: 下午 7:30
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 分页条的开始 --%>
<div id="page_nav">
<%-- 大于首页,才显示 --%>
<c:if test="${requestScope.page.pageNo > 1}">
<a href="${ requestScope.page.url }&pageNo=1">首页</a>
<a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageNo-1}">上一页</a>
</c:if>
<%-- 页码输出的开始 --%>
<c:choose>
<%-- 情况1:如果总页码小于等于5的情况,页码的范围是:1-总页码 --%>
<c:when test="${requestScope.page.pageTotal <= 5}">
<c:set var="begin" value="1" />
<c:set var="end" value="${requestScope.page.pageTotal}" />
</c:when>
<%-- 情况2:总页码大于5的情况。 --%>
<c:when test="${requestScope.page.pageTotal > 5}">
<c:choose>
<%--小情况 1:当前页码为前面 3 个:1,2,3 的情况,页码范围是:1-5.--%>
<c:when test="${requestScope.page.pageNo <= 3}">
<c:set var="begin" value="1" />
<c:set var="end" value="5" />
</c:when>
<%-- 小情况 2:当前页码为最后 3 个,8,9,10,页码范围是:总页码减 4 - 总页码 --%>
<c:when test="${requestScope.page.pageNo >= requestScope.page.pageTotal - 3}">
<c:set var="begin" value="${requestScope.page.pageTotal - 4}" />
<c:set var="end" value="${requestScope.page.pageTotal}" />
</c:when>
<%-- 小情况 3:4,5,6,7,页码范围是:当前页码减 2 - 当前页码加 2 --%>
<c:otherwise>
<c:set var="begin" value="${requestScope.page.pageNo - 2}" />
<c:set var="end" value="${requestScope.page.pageNo + 2}" />
</c:otherwise>
</c:choose>
</c:when>
</c:choose>
<c:forEach begin="${begin}" end="${end}" var="i">
<c:if test="${i == requestScope.page.pageNo}">
【${i}】
</c:if>
<c:if test="${i != requestScope.page.pageNo}">
<a href="${ requestScope.page.url }&pageNo=${i}">${i}</a>
</c:if>
</c:forEach>
<%-- 页码输出的结束 --%>
<%-- 如果已经 是最后一页,则不显示下一页,末页 --%>
<c:if test="${requestScope.page.pageNo < requestScope.page.pageTotal}">
<a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageNo+1}">下一页</a>
<a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageTotal}">末页</a>
</c:if>
共${requestScope.page.pageTotal}页,${requestScope.page.pageTotalCount}条记录
到第<input value="${param.pageNo}" name="pn" id="pn_input"/>页
<input id="searchPageBtn" type="button" value="确定">
<script type="text/javascript">
$(function () {
// 跳到指定的页码
$("#searchPageBtn").click(function () {
var pageNo = $("#pn_input").val();
var pageTotal = ${requestScope.page.pageTotal};
if (pageNo < 1) {
pageNo = 1;
location.href = "${pageScope.basePath}${ requestScope.page.url }&pageNo=" + pageNo;
pageNo.val(1)
}
if (pageNo > pageTotal) {
pageNo = pageTotal;
location.href = "${pageScope.basePath}${ requestScope.page.url }&pageNo=" + pageNo;
pageno.val(pageTotal)
}
// javaScript语言中提供了一个Location地址栏对象
// 它有一个属性叫href. 它可以获取浏览器地址栏中的地址
// href属性可读,可写
location.href = "${pageScope.basePath}${ requestScope.page.url }&pageNo=" + pageNo;
})
})
</script>
</div>
<%-- 分页条的结束 --%>
5、首页价格搜索
ClientBookServlet.java
/**
* 处理按价格查找 分页功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void pageByPrice(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取请求的参数 pageNo 和 pageSize
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"),1);
int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);
int min = WebUtils.parseInt(req.getParameter("min"),0);
int max = WebUtils.parseInt(req.getParameter("max"), Integer.MAX_VALUE);
// 2. 调用BookService.page(pageNo,PageSize):Page对象
Page<Book> page = bookService.pageByPrice(pageNo,pageSize,min,max);
StringBuilder sb = new StringBuilder("client/bookServlet?action=pageByPrice");
// 如果有最小价格的参数,追加到分页条的地址参数中
if (req.getParameter("min") != null) {
sb.append("&min=").append(req.getParameter("min"));
}
// 如果有最大价格的参数,追加到分页条的地址参数中
if (req.getParameter("max") != null) {
sb.append("&max=").append(req.getParameter("max"));
}
page.setUrl(sb.toString());
// 3. 保存Page对象到Request域中
req.setAttribute("page",page);
// 4. 请求转发到/pages/client/index.jsp页面
req.getRequestDispatcher("/pages/client/index.jsp").forward(req,resp);
}
BookServiceImpl.java
@Override
public Page<Book> pageByPrice(int pageNo, int pageSize, int min, int max) {
Page<Book> page = new Page<Book>();
// 设置每页显示的数量
page.setPageSize(pageSize);
// 求总记录数
Integer pageTotalCount = bookDao.queryForPageTotalCountByPrice(min, max);
// 设置总记录数
page.setPageTotalCount(pageTotalCount);
// 求总页码
Integer pageTotal = pageTotalCount / pageSize;
if (pageTotalCount % pageSize > 0){
pageTotal += 1;
}
// 设置总页码
page.setPageTotal(pageTotal);
// 设置当前页码
page.setPageNo(pageNo);
// 求当前页数据的开始索引
int begin = (page.getPageNo() - 1) * pageSize;
// 求当前页数据
List<Book> items = bookDao.queryForPageItemsByPrice(begin,pageSize,min,max);
// 设置当前页数据
page.setItmes(items);
return page;
}
BookDaoImpl.java
@Override
public Integer queryForPageTotalCountByPrice(int min, int max) {
String sql = "select count(*) from t_book where price between ? and ?";
Number count = (Number) queryForSingleValue(sql,min,max);
return count.intValue();
}
@Override
public List<Book> queryForPageItemsByPrice(int begin, int pageSize, int min, int max) {
String sql = "select id,name,author,price,sales,stock,img_path imgpath " +
"from t_book where price between ? and ? order by price limit ?,?";
return queryForList(Book.class,sql,min,max,begin,pageSize);
}
index.jsp
<form action="client/bookServlet" method="get">
<input type="hidden" name="action" value="pageByPrice">
价格:<input id="min" type="text" name="min" value="${param.min}"> 元 -
<input id="max" type="text" name="max" value="${param.max}"> 元
<input type="submit" value="查询" />
</form>