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

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

  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. finally中关闭资源

    对finally中关闭资源是否还要使用try...catch老是感到迷惑,现在存个例子,省的忘了 public StringBuilder readTxtFile(File file){ String ...

  2. springMVC中@RequestParam和@RequestBody注解的用法

    springMVC中@RequestParam注解用在Controller层获解析.提取参数,当然你也可以用request.getParameter("name")来获取参数,而@ ...

  3. IEEE754 处理数据变换

    public  class IEEE754 { /// <summary> /// 将二进制值转ASCII格式十六进制字符串 /// </summary> /// <pa ...

  4. CURL模拟post请求上传文件

    贴一段醍醐灌顶的话: 逻辑很简单,设置POST变量$post_data,其中upload指向需要发送的文件.这里要注意,我们之前使用POST都是发送一个字符串,然后在服务器端使用file_get_co ...

  5. 关于awk的范围模式功能问题

    关于awk的范围模式功能问题 man awk中这样写到 The pattern1, pattern2 form of an expression is called a range pattern. ...

  6. Nginx+Geoserver部署所遇问题总结

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 该问题的最终解决离不开公司大拿whs先生的指点,先表示感谢. ...

  7. Java在已存在的pdf文件中生成文字和图片--基础

    自我总结,有什么不足之处请告知,感激不尽!下一次总结pdf模板映射生成报表(应对多变的pdf报表需求,数据提供和报表生成解耦). 目的:在给定的pdf模板上生成报表,就需要知道最基本的操作:文字添加, ...

  8. JAVA设计模式之---工厂模式

    1.引言 工厂模式可以分为类: 1)简单工厂模式(Simple Factory) 2)工厂方法模式(Factory Method) 3)抽象工厂模式(Abstract Factory)  这种模式从上 ...

  9. if语句中同时判断多个条件的多种方法

    总结一下自己经常用到的python中的if语句同时判断多个条件的不同方法,假设有: x, y, z = 0, 1, 0 方法一,多个逻辑运算符一起使用,这也是最常用的写法: if x == 1 or ...

  10. 浅谈python的对象的三大特性之封装

    我们家里都有电视机,从开机,浏览节目,换台到关机,我们不需要知道电视机里面的具体细节,只需要在用的时候按下遥控器就可以完成操作,这就是功能的封装. 在用支付宝进行付款的时候,只需要在用的时候把二唯码给 ...