寒假结束了,自己的颓废时间同样结束了,早该继续写博客了,尽管我的格式以及内容由于各种原因老被卡,但必须坚持写下去!!!

  上次我们对于本案例的数据库部分进行了阐述,这次主要接着上次的内容分享本案例的翻页操作,其演示如下:

  GIF 中主要演示了翻页操作,首先进入该页面前先查询数据库中所有书籍的数量,根据每页显示的数量生成首页部分数据。

  1. 点击 “下一页”,当前第几页数字改变,页面显示下一页书籍信息;

  2. 点击 “上一页”,当前第几页数字改变,页面显示上一页书籍信息;

  3. 点击 “末页”,根据数据库信息显示最后一页的信息,此时页面上没有 “下一页” 超链接;

  4. 点击 “首页”,页面信息跳转到首页信息,此时页面上没有 “上一页” 超链接;

  5. 可以在输入框中输入数字直接跳转到你输入的页面,倘若输入错误的数字以及非数字将会跳转到首页

一、 操作准备条件

  1. 我们将显示页面封装为一个类(Page<T>,页面所要显示的不仅仅是 Book,也可能是其他类型所以为其加上泛型),其包含的成员变量有当前页面所要显示的书籍的列表(List<T> pageList),当前页页码(int pageNo),每页可显示的书籍数量(int pageSize)以及对于该数据库共多少页(long totalItemNum),在本类中我们还利用 totalItemNum 和 pageSize 获得对于当前数据库中的数据共有多少页(int totalPageNum),我们还根据当前页码进行判断是否存在下一页或者上一页并获取下一页和上一页的页码。

 package com.book.store.web;

 import java.util.List;

 /**
* 封装首页显示的页面
*/
public class Page<T> {
private int pageNo;
private List<T> pageList;
private int pageSize;
private long totalItemNum; /*
* 在这里我们将每页可显示的书籍数量设为 5
* */
public Page(int pageNo) {
pageSize = 5;
this.pageNo = pageNo;
} /*
* 对输入的页码进行纠正判断,若小于 0 则使其等于 1,若大于最大的页码则使其等于页码的最大值并返回
* */
public int getPageNo() {
if (pageNo < 0) {
pageNo = 1;
} if (pageNo > getTotalPageNum()) {
pageNo = getTotalPageNum();
}
return pageNo;
} public int getPageSize() {
return pageSize;
} public List<T> getPageList() {
return pageList;
} public void setPageList(List<T> pageList) {
this.pageList = pageList;
} public long getTotalItemNum() {
return totalItemNum;
} public void setTotalItemNum(long totalItemNum) {
this.totalItemNum = totalItemNum;
}
/*
* 根据 totalItemNum 和 pageSize 获取总页数
* */
public int getTotalPageNum() {
int flag = (int) (getTotalItemNum() % getPageSize());
int totalPageNum = (int) (getTotalItemNum() / getPageSize());
if (flag > 0) {
totalPageNum++;
}
return totalPageNum;
}
/*
* 判断是否有下一页
* */
public boolean isHasNext() {
if (getPageNo() == getTotalPageNum()) {
return false;
}
return true;
}
/*
* 判断是否有上一页
* */
public boolean isHasPrev() {
if (getPageNo() == 1) {
return false;
}
return true;
}
/*
* 获取下一个的 页码
* */
public int getNextPage() {
if (isHasNext()) {
return pageNo + 1;
}
return pageNo;
}
/*
* 获取上一页的页码
* */
public int getPrevPage() {
if (isHasPrev()) {
return pageNo - 1;
}
return pageNo;
} @Override
public String toString() {
return "Page{" +
"pageNo=" + pageNo +
", pageList=" + pageList +
", pageSize=" + pageSize +
", totalItemNum=" + totalItemNum +
'}';
}
}

  2. 封装查询条件为一个单独的类( CriteriaBook),其包括页面上部的查询条件最低价(int minPrice)和最高价(int maxPrice)区间和页面底部转到多少页的条件(int pageNo),并为其赋初值,极端值。

package com.book.store.web;

/**
* 封装查询条件的类
*/
public class CriteriaBook {
private int minPrice = 0;
private int maxPrice = Integer.MAX_VALUE;
private int pageNo; public CriteriaBook() {} @Override
public String toString() {
return "CriteriaBook{" +
"minPrice=" + minPrice +
", maxPrice=" + maxPrice +
", pageNo=" + pageNo +
'}';
} public CriteriaBook(int minPrice, int maxPrice, int pageNo) {
this.minPrice = minPrice;
this.maxPrice = maxPrice;
this.pageNo = pageNo;
} public int getMinPrice() {
return minPrice;
} public void setMinPrice(int minPrice) {
this.minPrice = minPrice;
} public int getMaxPrice() {
return maxPrice;
} public void setMaxPrice(int maxPrice) {
this.maxPrice = maxPrice;
} public int getPageNo() {
return pageNo;
} public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}
}

二、 编写思路以及步骤

  1. 在到达显示页面之前我们首先需要其显示首页信息,因为我们通过一个页面重定向到 Servlet 中,在 Servlet 中获取首页信息后将其包装在 request 中转发到显示页面!

 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>BookStore</title>
</head>
<body>
<h3><%
/*
* /days_1212_JavaWebBookStore,query 方法中负责封装数据并返回显示页面
* */
response.sendRedirect(request.getContextPath() + "/query.do");
System.out.println(request.getContextPath());
%></h3>
</body>
</html>

  2. query 方法要封装信息就需要查询数据库,所以为了 query 方法的简洁明了我们将逻辑方法置于一个单独的类。在 query 方法中我们将查询条件都赋初值,以免在没有查询条件的情况下不会出错,方法中我们给三个查询条件分别加以异常处理为了使假若其中一个出错不会影响其他的查询条件(以下为Servlet 的 query 方法)。

 protected void query(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取查询条件之最低价
String minPriceStr = request.getParameter("minPrice");
// 获取查询条件之最高价
String maxPriceStr = request.getParameter("maxPrice");
// 获取查询条件之页码
String pageNoStr = request.getParameter("pageNo");
// 初始化查询条件,即无查询条件的默认值
int minPrice = 0;
int maxPrice = Integer.MAX_VALUE;
int pageNo = 1; try {
minPrice = Integer.parseInt(minPriceStr);
} catch (NumberFormatException e) {}
try {
maxPrice = Integer.parseInt(maxPriceStr);
} catch (NumberFormatException e) {}
try {
pageNo = Integer.parseInt(pageNoStr);
} catch (NumberFormatException e) {}
// 构建查询条件所对应的类
CriteriaBook criteriaBook = new CriteriaBook(minPrice, maxPrice, pageNo);
// 根据查询条件获得首页显示信息所构建的类
Page<Books> page = bookService.getPage(criteriaBook);
// 将首页需要显示的信息存入 request 中,用于显示
request.setAttribute("page", page);
// 转发回首页
request.getRequestDispatcher("/showView/bookList.jsp").forward(request, response);
}

  3. 上述方法中从页面获取查询条件将其封装为对应的类(CriteriaBook),再根据查询条件所封装的类构建 Page 类(BookDao 接口所要实现的功能之一,方法 getPage(CriteriaBook criteriaBook) )!Page 类包括了所要显示的书籍,根据书籍数量获得共多少页,共多少书籍等信息。我们在 getPage 方法中首先新建 Page 对象,然后利用 setXxx 方法为 page 对象赋值。

     /*
* 初始化首页显示页
* */
@Override
public Page<Books> getPage(CriteriaBook criteriaBook) {
// 在新建 page 对象的时候就初始化页码(pageNo)
Page<Books> page = new Page<Books>(criteriaBook.getPageNo());
// 设置现显示页的总数量(需要根据总数量和 pageSize 计算共多少页)
page.setTotalItemNum(getTotalNum(criteriaBook));
// 设置查询条件的页码(利用 Page 类中的 getPageNo 使页码合法)
criteriaBook.setPageNo(page.getPageNo());
// 初始化显示页的 list 集合
page.setPageList(getBookList(criteriaBook, 5));
return page;
}

  4. 上述 getPage(CriteriaBook criteriaBook) 方法中所调用的 getTotalNum(criteriaBook) 方法以及 getBookList(criteriaBook,pageSize) 均需要结合数据库数据方可完成赋值。

 /*
* 根据查询条件获取该条件下商品的总数量
* */
@Override
public long getTotalNum(CriteriaBook criteriaBook) {
String sql = "SELECT COUNT(id) FROM books WHERE price>=? AND price<=?";
long totalNum = (Long) getCount(sql, criteriaBook.getMinPrice(), criteriaBook.getMaxPrice());
return totalNum;
} /*
* 根据查询条件(最高价、最低价、)和每页显示的数量(pageSize)获取对应商品的 list 集合
* */
@Override
public List<Books> getBookList(CriteriaBook criteriaBook, int pageSize) {
String sql = "SELECT id, author, title, price, publish_date publishDate, sales_count salesCount, store_number storeNumber, remark " +
"FROM books WHERE price >= ? AND price <= ? LIMIT ?, ?";
List<Books> booksList = getList(sql,criteriaBook.getMinPrice(), criteriaBook.getMaxPrice(), (criteriaBook.getPageNo() - 1) * pageSize, pageSize);
return booksList;
}

  5. 到这里我们已经成功将首页信息获取到,接下来需要将获取到的信息显示到页面,首先我们将 page 对象添加到 request 域中通过请求转发至页面并在页面利用 JSTL 将其进行显示。接着为 “上一页”、“下一页”、“首页”、“末页” 等超链接添加响应事件。为上述超链接添加超链接的时候其 href 属性是重点,我们利用 href 属性将其链接到 servlet 中的 query 方法中,在 servlet 方法中进行处理对应的操作!

 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>BookList</title>
<%@ include file="/commons/queryCondition.jsp" %>
</head>
<body>
<div>
<form method="post" action="${pageContext.request.contextPath}/query.do">
Price: <input type="text" size="1" name="minPrice">&nbsp;-&nbsp;
<input type="text" size="1" name="maxPrice">
<button type="submit">Submit</button>
</form>
<table cellpadding="15">
<c:forEach items="${requestScope.page.pageList}" var="book">
<tr>
<td>
<a href="${pageContext.request.contextPath}/getBookInfo.do?id=${book.id}&pageNo=${requestScope.page.pageNo}">${book.title}</a><br>${book.author}
</td>
<td>${book.price}</td>
<td><a href="#">加入购物车</a></td>
</tr>
</c:forEach>
</table>
<br><br>
<span>共${requestScope.page.totalPageNum}页&nbsp;&nbsp;当前第${requestScope.page.pageNo}页</span>
<c:if test="${requestScope.page.hasPrev}">
<span><a href="${pageContext.request.contextPath}/query.do?pageNo=1">首页</a>&nbsp;
<a href="${pageContext.request.contextPath}/query.do?pageNo=${requestScope.page.prevPage}">上一页</a></span>
</c:if>
<c:if test="${requestScope.page.hasNext}">
<span><a href="${pageContext.request.contextPath}/query.do?pageNo=${requestScope.page.nextPage}">下一页</a>&nbsp;
<a href="${pageContext.request.contextPath}/query.do?pageNo=${requestScope.page.totalPageNum}">尾页</a></span>
</c:if>
转到&nbsp; <input type="text" size="1" name="toPage" id="pageNo"> &nbsp;页
</div>
</body>
</html>

  6. 上述代码中翻页的超链接点击之后伴随 nextPageNo 或 prePageNo 参数传递到 Servlet 中的 query 方法中进行处理,此时的 query 方法中除了 pageNo(利用 request 参数以及 JSTL 调用 Page 类中的 getXxx 方法结合构造器中的 pageNo 参数得到 nextPageNo 和 prePageNo) 参数其余的均为初始值,所以其处理过程如上显示首页一般,至于转到多少多少页我们使用 Ajax 及时响应请求并处理!

   <script type="text/javascript" src="${pageContext.request.contextPath}/jquery-1.7.2.js"></script>
<script type="text/javascript">
$(function () {
$("#pageNo").change(function () {
var $pageVal = $("#pageNo").val()
window.location.href = "${pageContext.request.contextPath}/query.do?pageNo=" + $pageVal;
})
});
</script>

  

  7. 上述代码中利用 JS 对 id 为 pageNo 的输入框进行监测,若其值变化则执行 Ajax 函数,新建变量($pageNo)为其赋值为所输入的值,然后将请求的发送到 window.location.href ,即 query 方法执行查询!

  至此我们就将本案例中的翻页操作讲述完毕,如果阅读过程过有更好的方法或者发现什么问题还望大家可以提出,我将及时更正,谢谢!!!

WEB 小案例 -- 网上书城(二)的更多相关文章

  1. WEB 小案例 -- 网上书城(一)

    距离上次写博客有两周了吧,最多的原因就是自己期末考试了,上课没听就只能在期末狠狠的复习了,毕竟已经挂科了.当然还是因为自己懒吧!!!废话不多说开始我们今天的正题,网上书城! 一. 新建数据表(MySQ ...

  2. WEB 小案例 -- 网上书城(四)

    针对于这个小案例我们今天讲解结账操作,也是有关这个案例的最后一次博文,说实话这个案例的博文写的很糟糕,不知道该如何去表述自己的思路,所以内容有点水,其实说到底还是功力不够. 处理思路 点击结账,发送结 ...

  3. Web 小案例 -- 网上书城(三)

    内容有点乱,有兴趣的同伙可依照后面的案例结构结合文章进行阅读 和网上购买东西一样,你可以在不登录的状态下去浏览商品,但是当你想把自己中意的东西加入购物车或是收藏起来就需要你拥有自己的账号然后登录后才可 ...

  4. Android JSON解析库Gson和Fast-json的使用对比和图书列表小案例

    Android JSON解析库Gson和Fast-json的使用对比和图书列表小案例 继上篇json解析,我用了原生的json解析,但是在有些情况下我们不得不承认,一些优秀的json解析框架确实十分的 ...

  5. 8天入门docker系列 —— 第五天 使用aspnetcore小案例熟悉容器互联和docker-compose一键部署

    这一篇继续完善webnotebook,如果你读过上一篇的内容,你应该知道怎么去挂载webnotebook日志和容器的远程访问,但是这些还远不够,webnotebook 总要和一些数据库打交道吧,比如说 ...

  6. 大项目之网上书城(五)——主页(End)

    目录 大项目之网上书城(五)--主页(End) 主要改动 1.主页(终于完成啦) 完整代码 效果图 2.head.jsp的小改动 代码 3.login.jsp ###代码 效果图 4.login.js ...

  7. 一个简单的Maven小案例

    Maven是一个很好的软件项目管理工具,有了Maven我们不用再费劲的去官网上下载Jar包. Maven的官网地址:http://maven.apache.org/download.cgi 要建立一个 ...

  8. IIS7.5使用web.config设置伪静态的二种方法

    转自 网上赚钱自学网 .http://www.whosmall.com/post/121 近几天公司里开发的项目有几个运行在IIS7.5上,由于全站采用的是伪静态,因此从网上找到两两种方法来实现.这两 ...

  9. shell讲解-小案例

    shell讲解-小案例 一.文件拷贝输出检查 下面测试文件拷贝是否正常,如果cp命令并没有拷贝文件myfile到myfile.bak,则打印错误信息.注意错误信息中basename $0打印脚本名.如 ...

随机推荐

  1. java判断时间大小

    //构造日期格式yyyy-MM-NN SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); Date d ...

  2. Macaca拓展自己控件的方法

    https://github.com/macacajs/wd.py/blob/3bc4334bcb68733cb230b59d6164110053fd1c16/tests/macaca/test_ut ...

  3. 如何使用 highlight.js 高亮代码

    highlight 是一款简单易用的 web 代码高亮插件,可以自动检测编程语言并高亮,兼容各种框架,可以说是十分强大了.下面就简单介绍一下如何使用这款插件. 两种使用方式: 1. 手动选择主题,官网 ...

  4. svn一整套使用,从下载到整个服务器搭建完成的详细说明

    SVN服务器的本地搭建和使用 Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网站上 ...

  5. CSS学习笔记(一):定位与溢出

    一.定位:positionstatic | relative | absolute | fixed | inherit ,各值含义如下: 1)static:元素框正常生成,块级元素生成一个矩形框,作为 ...

  6. linux下硬盘uuid查看及修改设置

    查看硬盘UUID 方法一:ls -l /dev/disk/by-uuid方法二:blkid /dev/sdb1 修改硬盘UUID: uuidgen 会返回一个合法的 uuid,结合 tune2fs 可 ...

  7. ABP官方文档翻译 6.4 导航

    导航 创建菜单 注册导航提供者 显示菜单 每一个网络应用都会有一些菜单用来在pages/screens之间导航.ABP提供了通用的基础设施来创建并显示菜单. 创建菜单 应用可以由不同的模块组成,每一个 ...

  8. bzoj 3996: [TJOI2015]线性代数 [最小割]

    3996: [TJOI2015]线性代数 题意:给出一个NN的矩阵B和一个1N的矩阵C.求出一个1*N的01矩阵A.使得 \(D=(A * B-C)* A^T\)最大.其中A^T为A的转置.输出D.每 ...

  9. BZOJ 3160: 万径人踪灭 [fft manacher]

    3160: 万径人踪灭 题意:求一个序列有多少不连续的回文子序列 一开始zz了直接用\(2^{r_i}-1\) 总-回文子串 后者用manacher处理 前者,考虑回文有两种对称形式(以元素/缝隙作为 ...

  10. BZOJ 2064: 分裂 [DP 状压 转化]

    传送门 题意:一开始$n$块面积最后$m$块面积,面积和相等每次可以分裂或者合并,问最少几次 昨天忘发了... 不会.... 考虑最差情况,$n+m-2$所有先合并再分裂 发现只有当前后两个子集相等时 ...