一、分页功能模块的分析
(一) 首页 index.jsp 的跳转
1)web目录下的index.jsp只做请求转发的功能
2)client目录下的index.jsp,是根据查询的到的分页数据,然后使用JSTL标签库遍历数据输出到页面上
二、分页模型Page抽取 (当前页数,总页数,总记录数, 当前页数据,每页记录数)
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> items;
// 分页条的请求地址
private String url;
@Override
public String toString() {
return "Page{" +
"pageNo=" + pageNo +
", pageTotal=" + pageTotal +
", pageSize=" + pageSize +
", pageTotalCount=" + pageTotalCount +
", items=" + items +
", url='" + url + '\'' +
'}';
}
public Page() {
}
public Page(Integer pageNo, Integer pageTotal, Integer pageSize, Integer pageTotalCount, List<T> items,
String url) {
this.pageNo = pageNo;
this.pageTotal = pageTotal;
this.pageSize = pageSize;
this.pageTotalCount = pageTotalCount;
this.items = items;
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> getItems() {
return items;
}
public void setItems(List<T> items) {
this.items = items;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
三、设置Servlet程序
/**
* 处理图书页面分页功能
*
* @return void
* @author weisn
* @date 22:06
*/
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);
//3 保存Page对象到Request域中
req.setAttribute("page", page);
//4 设置url的分页请求地址
page.setUrl("bookServlet?action=page");
//5 请求转发到pages/manager/book_manager.jsp页面
req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req, resp);
}
三、设置Service程序
1)根据Servlet程序所要用到的方法,设置一个Service程序
public Page<Book> page(int pageNo, int pageSize) {
//1.创建一个page分页对象
Page<Book> page = new Page<Book>();
//2.给page对象进行赋值
//设置每一页显示的数量
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.quqeryForPageItems(begin, pageSize);
page.setItems(items);
return page;
}
四、设置Dao层
1)根据Service层所需要查询到的结果,编写Dao去操作数据库
public Integer queryForPageTotalCount() {
String sql = "select count(*) from t_book";
Number count = (Number) queryForSingleValue(sql);
return count.intValue();
}
public List<Book> quqeryForPageItems(int begin, int pageSize) {
String sql = "select `id` , `name` , `author` , `price` , `sales` , `stock` , `img_path` imgPath from t_book " +
"limit ?,?";
return querForList(Book.class, sql, begin, pageSize);
}
五、需要去修改jsp页面中的请求地址
将请求地址改为所对应执行分页的Servlet程序。也就行将action=(对应的方法名)如下:
六、jsp页面遍历显示
1)从request域中去遍历查询到的数据显示出来
<%--循环遍历显示开始--%>
<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>
<%--循环遍历显示结束--%>
七、分页条的实现(首页、上一页、下一页、末页,分页模块中跳转到指定页数功能)
1)把他抽取出来当一个独立的jsp页面,然后用静态包含把他引用到所需要的页面中去
2)里面的转发地址用url表示,只需要在对应的Servlet程序中设置url的分页请求地址,例如:
3) 页码的显示情况
需求:显示 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
<%-- 分页条的开始 --%>
<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>
<%-- 情况一:如果总页码小于等于5的情况,页码的范围是:1-总页码 --%>
<c:when test="${requestScope.page.pageTotal<=5}">
<%-- <c:set var ="" value="" ></c:set> 是给属性设置值 --%>
<c:set var="begin" value="1"></c:set>
<c:set var="end" value="${requestScope.page.pageTotal}"></c:set>
</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="${requestScope.page.pageNo}" name="pn" id="pn_input"/>页
<input id="searchPPageBtn" type="button" value="确定">
<%-- 分页模块中跳转到指定页数功能实现 --%>
<script>
$(function () {
$("#searchPPageBtn").click(function () {
// 在前端校验输入的页码是否合法
var pageNo = $("#pn_input").val();
var pageTotal =${requestScope.page.pageTotal};
if (pageNo > 1 && pageNo == 1 && pageNo < pageTotal && pageNo == pageTotal)
location.href = "http://localhost:8080${requestScope.page.url}&pageNo=" + pageNo;
});
});
</script>
</div>
<%--分页条的结束--%>
八、修改分页后,增加,删除,修改图书信息的回显页面
1)在修改的请求地址上追加当前页码参数:
2)在 对应的 页面中使用隐藏域记录下 pageNo 参数
3)在服务器重定向的时候,获取当前页码追加上进行跳转
九、首页价格搜索
1)也是跟上面差不多,只不过是查询dao的时候多了个最小价钱和最大价钱的查询条件,得到的结果并不相同
2)
(一)设置Servlet程序
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 stringBuilder=new StringBuilder("clientBookServlet?action=pageByPrice");
//如果有最小价格的请求参数,追加到分页条的参数中
if (req.getParameter("min")!=null){
stringBuilder.append("&min=").append(req.getParameter("min"));
}
//如果有最大价格的请求参数,追加到分页条的参数中
if (req.getParameter("max")!=null){
stringBuilder.append("&max=").append(req.getParameter("max"));
}
//3 保存Page对象到Request域中
req.setAttribute("page", page);
//4 设置url的分页请求地址
page.setUrl(stringBuilder.toString());
//5 请求转发到pages/client/book_manager.jsp页面
req.getRequestDispatcher("/pages/client/index.jsp").forward(req, resp);
}
(二)设置Service程序
其实也就是公用一个Service程序,只不过是多了一个查询方法
(三)设置Dao程序
其实也就是公用一个Dao程序,只不过是多了一个查询数据库操作