书城项目-第五阶段:图书分页模块

书城项目-第五阶段:图书分页的分析、书城项目-分页模型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>
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇