JavaWeb书城项目(六)——图书分页

前五个部分我们已经完成了用户的注册与登录模块,以及后台的图书管理,第六部分我们完成图书的分页部分,分页的原因就是一页显示全部信息太繁杂了,所以需要需要分页来解决这个问题。

分页模块的分析

分页模块的分析


分页模型Page的抽取

由分页的视图分析出分页的对象模型Page类有如下属性

/**
 * 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<Book> items;

分页的初步实现

BookDao代码

    @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);
    }

BookService代码

    @Override
    public Page<Book> page(int pageNo, int pageSize) {
        Page<Book> page = new Page<Book>();
        // 设置当前页码
        page.setPageNo(pageNo);
        // 设置每页显示的数量
        page.setPageSize(pageSize);
        // 求总记录数
        Integer pageTotalCount = bookDao.queryForPageTotalCount();
        // 设置总记录数
        page.setPageTotalCount(pageTotalCount);
        // 求总页码
        Integer pageTotal = pageTotalCount / pageSize;
        if (pageTotalCount % pageSize > 0){
            pageTotal+=1;
        }
        // 设置总页码
        page.setPageTotal(pageTotal);
        // 求当前页数据的开始索引
        int begin = (page.getPageNo() - 1) * pageSize;
        // 求当前页数据
        List<Book> items = bookDao.queryForPageItems(begin, pageSize);
        // 设置当前页数据
        page.setItems(items);

        return page;
    }

BookServlet程序的代码

   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);
        //3 保存 Page 对象到 Request 域中
        req.setAttribute("page", page);
        //4 请求转发到pages/manager/book_manager.jsp页面
        req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);
    }

manager_menu.jsp中图书管理请求地址的修改
修改图书管理请求地址
book_manager.jsp修改
book_manager.jsp修改(一)
book_manager.jsp修改(二)


首页,上一页,下一页,末页实现

修改book_manager.jsp
修改book_manager.jsp


实现跳到指定页数

修改book_manager.jsp,通过绑定单击事件实现跳到指定页数
修改book_manager.jsp
Page对象的修改,完成数据边界的有效检查,使其不会跳到没有的页数

public void setPageNo(Integer pageNo) {
/* 数据边界的有效检查 */
if (pageNo < 1) {
pageNo = 1;
}
if (pageNo > pageTotal) {
pageNo = pageTotal;
}
this.pageNo = pageNo;
}

与之对应,要修改 BookServicepage方法,因为设置当前页码时,需要 pageTotal 来进行数据边界的有效检查,所以设置当前页码要放在设置总页码之后。
修改BookService中page方法


页码的显示

一般来说,显示页码的时候,不仅会显示当前页的页码,还会显示前几页的页码,以及后几页的页码,然后点击这些页码就可以跳转到指定页。
这里实现一次显示5个页码,下面分情况讨论:

情况1:
	如果总页码小于等于5,页码的范围是:1~总页码
	11
	212
	3123
	41234
	512345
情况2:
	总页码大于5的情况。假设一共10页
	小情况1:当前页码为前面2个,页码的范围是:1~5
	[1],2,3,4,5
	1,[2],3,4,5
	小情况2:当前页码为最后2个,页码的范围是:总页码-4~总页码
	6,7,8,[9],10
	6,7,8,9,[10]
	小情况3:其它情况,页码的范围是:当前页码-2~当前页码+2
	2,3,[4],5,6
	3,4,[5],6,7

按照上面的情况修改 book_manager.jsp

			<c:choose>
			<%--情况1:如果总页码小于等于5--%>
			<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:当前页码为前面2--%>
				<c:when test="${requestScope.page.pageNo < 3}">
					<c:set var="begin" value="1"/>
					<c:set var="end" value="5"/>
				</c:when>
				<%--小情况2:当前页码为最后2--%>
				<c:when test="${requestScope.page.pageNo > requestScope.page.pageTotal-2}">
					<c:set var="begin" value="${requestScope.page.pageTotal-4}"/>
					<c:set var="end" value="${requestScope.page.pageTotal}"/>
				</c:when>
				<%--小情况3:其他情况--%>
				<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="manager/bookServlet?action=page&pageNo=${i}">${i}</a>
				</c:if>
			</c:forEach>

修改分页后,增加,删除,修改图书信息的回显页面

以修改图书为例
1.在修改的请求地址上追加当前页码参数
修改book_manager,jsp
2. 在book_edit.jsp页面中使用隐藏域记录下pageNo参数
使用隐藏域记录下pageNo参数

  1. 在服务器重定向时,获取当前页码追加上进行跳转
    追加当前页码进行跳转

首页index.jsp的跳转

因为首页也需要分页,所以我们访问首页的时候需要让其通过 ClientBookServlet程序让其跳转到 web目录/pages/client目录的/index.jsp
首页index.jsp的跳转
创建ClientBookServlet程序

package com.atguigu.web;

import com.atguigu.pojo.Book;
import com.atguigu.pojo.Page;
import com.atguigu.service.BookService;
import com.atguigu.service.impl.BookServiceImpl;
import com.atguigu.utils.WebUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ClientBookServlet extends BaseServlet{

    private BookService bookService = new BookServiceImpl();

    protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //System.out.println("经过了前台程序");
        //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);
    }

}

配置web.xml,增加ClientBookServlet的映射

    <servlet>
        <servlet-name>ClientBookServlet</servlet-name>
        <servlet-class>com.atguigu.web.ClientBookServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ClientBookServlet</servlet-name>
        <url-pattern>/client/bookServlet</url-pattern>
    </servlet-mapping>

创建client/index.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>
    <link type="text/css" rel="stylesheet" href="static/css/style.css" >
</head>
<body>

<div id="header">
    <img class="logo_img" alt="" src="static/img/logo.gif" >
    <span class="wel_word">网上书城</span>
    <div>
        <a href="pages/user/login.jsp">登录</a>
        <a href="pages/user/regist.jsp">注册</a> &nbsp;&nbsp;
        <a href="pages/cart/cart.jsp">购物车</a>
        <a href="pages/manager/manager.jsp">后台管理</a>
    </div>
</div>
<div id="main">
    <div id="book">
        <div class="book_cond">
            <form action="" method="get">
                价格:<input id="min" type="text" name="min" value="">-
                <input id="max" type="text" name="max" value=""><input type="submit" value="查询" />
            </form>
        </div>
        <div style="text-align: center">
            <span>您的购物车中有3件商品</span>
            <div>
                您刚刚将<span style="color: #ff0000">时间简史</span>加入到了购物车中
            </div>
        </div>
        <c:forEach items="${requestScope.page.items}" var="book">
        <div class="b_list">
            <div class="img_div">
                <img class="book_img" alt="" src="${book.imgPath}" />
            </div>
            <div class="book_info">
                <div class="book_name">
                    <span class="sp1">书名:</span>
                    <span class="sp2">${book.name}</span>
                </div>
                <div class="book_author">
                    <span class="sp1">作者:</span>
                    <span class="sp2">${book.author}</span>
                </div>
                <div class="book_price">
                    <span class="sp1">价格:</span>
                    <span class="sp2">¥${book.price}</span>
                </div>
                <div class="book_sales">
                    <span class="sp1">销量:</span>
                    <span class="sp2">${book.sales}</span>
                </div>
                <div class="book_amount">
                    <span class="sp1">库存:</span>
                    <span class="sp2">${book.stock}</span>
                </div>
                <div class="book_add">
                    <button>加入购物车</button>
                </div>
            </div>
        </div>
        </c:forEach>


    </div>

    <div id="page_nav">
        <a href="#">首页</a>
        <a href="#">上一页</a>
        <a href="#">3</a>4<a href="#">5</a>
        <a href="#">下一页</a>
        <a href="#">末页</a>10页,30条记录 到第<input value="4" name="pn" id="pn_input"/><input type="button" value="确定">
    </div>

</div>

<div id="bottom">
		<span>
			尚硅谷书城.Copyright &copy;2015
		</span>
</div>
</body>
</html>

修改web/index.jsp为请求转发到Servlet

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--只负责请求转发--%>
<jsp:forward page="/client/bookServlet?action=page"></jsp:forward>


分页条的抽取

前台页面也需要分页条,因为对于分页条而言,只是请求的 url 不同,我们可以给 page 添加 url 属性,再把分页条抽取出来,就可以简单的调用分页条。

  1. page 对象中添加 url 属性
    page对象中添加url属性

  2. Servlet 程序中的 page 分页方法中设置 url 的分页请求地址
    设置url的分页请求地址

  3. 修改分页条中请求地址为url变量输出,并抽取一个单独的page_nav.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div id="page_nav">
    <c:choose>
        <%--情况1:如果总页码小于等于5--%>
        <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:当前页码为前面2--%>
                <c:when test="${requestScope.page.pageNo < 3}">
                    <c:set var="begin" value="1"/>
                    <c:set var="end" value="5"/>
                </c:when>
                <%--小情况2:当前页码为最后2--%>
                <c:when test="${requestScope.page.pageNo > requestScope.page.pageTotal-2}">
                    <c:set var="begin" value="${requestScope.page.pageTotal-4}"/>
                    <c:set var="end" value="${requestScope.page.pageTotal}"/>
                </c:when>
                <%--小情况3:其他情况--%>
                <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: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: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};--%>
                // alert(pageTotal)
                // js语言中提供了一个 location 地址栏对象
                // 它有一个属性叫 href. 它可以获取浏览器中地址栏中的地址
                // href 属性可读可写
                location.href = "${pageScope.basePath}${requestScope.page.url}&pageNo="
                    + pageNo;
            });
        });
    </script>
</div>
  1. 静态包含page_nav.jsp
    静态包含page_nav.jsp

首页价格搜索

首页价格搜索
BookDao程序添加如下方法

    @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 ? limit ?,?";
        return queryForList(Book.class, sql, min, max, begin, pageSize);
    }

BookService程序添加如下方法

    @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.setItems(items);

        return page;
    }

ClientBookServlet程序添加如下方法,需要注意的是设置 url 需要加上 minmax参数,这样之后点击下一页之类的,才是按价格查询的。

    protected void pageByPrice(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //System.out.println("经过了前台程序");
        //1 获取请求的参数 pageNo 和 pageSize, min 和 max
        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.pageByPrice(pageNo, pageSize, min, max): 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);
    }
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值