客户信息管理系统9—客户信息的分页查询
6、功能六:分页查询
(1)物理分页和逻辑分页
【1】物理分页
1.1.1物理分页说明
在sql查询时,从数据库只检索分页需要的数据
通常不同的数据库有着不同的物理分页语句
mysql物理分页,采用limit关键字
例如:检索11-20条select * from user limit 10,10 ;
1.1.2物理分页实例
//物理分页
// 在sql查询时,从数据库只检索分页需要的数据
// 通常不同的数据库有着不同的物理分页语句。mysql物理分页,采用limit关键字
// 例如:检索11-20条 select * from user limit 10,10 ;
// 其中第1个10:表示开始索引位置
// 其中第2个10:表示记录数目
@Test
public void physicalPage(){
QueryRunner qr=new QueryRunner(JdbcUtils.getDatasourse());
try {
//检索第11-20条记录【10-19】(因为是从0开始计算)
List<Customers> customersList = qr.query("select * from customerslimit ?,?", new BeanListHandler(Customers.class),10,10);
for (int i = 0; i < customersList.size(); i++) {
System.out.println(customersList.get(i).toString());
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
【2】逻辑分页
1.2.1逻辑分页说明
在sql查询时,先从数据库检索出所有数据的结果集
在程序内,通过逻辑语句获得分页需要的的数据
例如: 检索11-20条 userList.subList(10,20);
1.2.2逻辑分页实例
//逻辑分页
// 在sql查询时,先从数据库检索出所有数据的结果集。在程序内,通过逻辑语句获得分页需要的的数据
// 例如: 检索11-20条 userList.subList(10,20);
@Test
public void logicalPage(){
QueryRunner qr=new QueryRunner(JdbcUtils.getDatasourse());
try {
List<Customers> customersList = qr.query("select * from customers", new BeanListHandler(Customers.class));
//检索第11-20条记录【10-19】(因为是从0开始计算)
customersList=customersList.subList(10,20);
for (int i = 0; i < customersList.size(); i++) {
System.out.println(customersList.get(i).toString());
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
【3】分页结论
分页查询的理论分为如上两种,最终代码显示的结果是两种效果是一样的,只是原理不同.
(2)分页查询思路分析
思考:如何只是单纯的把查询的信息带过去,就不能实现分页查询
原因:每次查询都是一个CustomersList。是固定的,下一次则无法使用,因为我们无法知道,每页记录数,总页数,总记录数,当前页数据,只是知道当前页数,所以无法实现分页查询
结论:我们要一个PageBean,去封装我们要的数据:每页记录数,总页数,总记录数,当前页数,当前页数据。用于我们下一次查询时使用
(3)分页查询时两个公式的推导
【1】总页数=(总记录条数+每页记录条数-1)/每页记录条数
分析:
总页数的获得,一开始,简单想,就是:总页数=总记录条数/每页记录条数;但是,这是当总记录条数可以整除每页记录条数,如果不能整除,实际上,总也数目是要加1的。因此,我们从这个角度考虑,只要考虑特殊的,可以整除的情况,其余是加1的。因此,就出现了:总页数=(总记录条数+每页记录条数)/每页记录条数的推导,但是,这是没有考虑特殊情况的加1,所以在进行稍微考虑后,再减1操作后,就可以保证除了整除之外的情况,进行加1操作;否则不加,因此,最终得到了这个公式:总页数=(总记录条数+每页记录条数-1)/每页记录条数
【2】开始索引位置=(当前页数-1)*每页记录条数
(4)分页标准
参考百度的分页:左5 当前页 右4
情况一:总共页数小于或者等于10页,设置中止页即可(开始页为1)
情况二:总共页数大于10页
此情况,考虑三种可能:
(1)左边:(当前页在1-10之间)
[端点]begin=1,end=10
(2)右边 :(当前页在倒数第10页和倒数第1页之间)
[端点]
begin=${pageBean.totalPage-9} end=${pageBean.totalPage}
(3)中间 [普通情况]
begin=${pageBean.currentPage-5>0?pageBean.currentPage-5:1}
end=${pageBean.currentPage+4<pageBean.totalPage?pageBean.currentPage+4:pageBean.totalPage}
(4)代码组成
PageBean+ index.jsp+pageQueryInfo.jsp+ PageQueryServlet+
CustomersService + CustomersDao + CustomersDaoImplement
(5)代码功能介绍
【1】PageBean:分页的实体类,封装分页相关的一些数据:每页记录数,总页数,总记录数,当前页数,当前页数据
【2】index.jsp页面:分页查询入口
【3】pageQueryInfo.jsp页面:分页查询信息显示页面
【4】 PageQueryServlet:分页查询web层
【5】CustomersService :业务层(pageQuery(currentPage)方法)
【6】CustomersDao:dao接口层(selectPageList(start,pageRecord)方法)
【7】CustomersDaoImplement:dao结构层实现类(selectPageList(start,pageRecord)方法)
(6)代码详细
6.6.1 PageBean:分页的实体类,封装分页相关的一些数据:每页记录数,总页数,总记录数,当前页数,当前页数据
packagecom.zhku.jsj144.zk.domain;
importjava.util.List;
//用于分页的bean
//总页数,总记录数,每页记录数,当前页数,当前页数据
public class PageBean {
private int totalPage;//总页数
private int totalRecord;//总记录数
private int pageRecord;//每页记录数
private int currentPage;//当前页数
private List<Customers> dataList;//当前页数据
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getTotalRecord() {
return totalRecord;
}
public void setTotalRecord(int totalRecord) {
this.totalRecord = totalRecord;
}
public int getPageRecord() {
return pageRecord;
}
public void setPageRecord(int pageRecord) {
this.pageRecord = pageRecord;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public List<Customers> getDataList() {
return dataList;
}
public void setDataList(List<Customers>dataList) {
this.dataList = dataList;
}
}
6.6.2index.jsp页面:分页查询入口
详细看功能二代码实现,已经写好了
6.6.3 pageQueryInfo.jsp页面 :分页查询信息显示页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'findAllCustomer.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script>
//删除确认对话框
function confirm_deleteOne(id) {
// alert(id);
var message = confirm("你确定要删除这条记录吗?");
if (message == true) {
window.location.href = "/customer_system/DeleteOneServlet?id=" + id;//正确
}
}
//全选或者全不选
function checkAll() {
//id="chooseFirst" 如果选中,下面的checkbox全部被选中
var chooseAll = document.getElementsByName("choose");//全部choose
var choose = document.getElementById("chooseFirst");//第一个choose
//选中状态:checked可以为true或者false
if (choose.checked) {
for (var i = 0; i < chooseAll.length; i++) {
chooseAll[i].checked = true;
}
}
//id="chooseFirst" 如果没有选中,下面的checkbox全部不选中
else {
for (var i = 0; i < chooseAll.length; i++) {
chooseAll[i].checked = false;
}
}
}
</script>
</head>
<body>
<h1 align="center">当前是第${pageBean.currentPage}页--客户信息查询列表</h1>
<table border="1" align="center">
<tr>
<!-- <td>编号</td> -->
<td>选中状态<input type="checkbox" name="choose" id="chooseFirst"
οnclick="checkAll()"></td>
<td>客户姓名</td>
<td>性别</td>
<td>生日</td>
<td>手机</td>
<td>电子邮件</td>
<td>客户爱好</td>
<td>客户类型</td>
<td>备注</td>
<td>状态</td>
</tr>
<c:forEach var="customer" items="${pageBean.dataList }">
<tr>
<!-- <td>${customer.id }</td> -->
<td><input type="checkbox" name="choose"
value="${customer.id }"></td>
<td>${customer.name }</td>
<td>${customer.gender }</td>
<td>${customer.birthday }</td>
<td>${customer.cellphone }</td>
<td>${customer.email }</td>
<td>${customer.preference }</td>
<td>${customer.type }</td>
<td>${customer.description }</td>
<!-- <td><a href="/customer_system/DeleteOneServlet?id=${customer.id }">删除</a></td> -->
<td><a href="javascript:void(0)"
οnclick="confirm_deleteOne('${customer.id}')">删除</a> <a
href="/customer_system/GetUpdateInfoServlet?id=${customer.id }">修改</a>
</td>
</tr>
</c:forEach>
</table>
<br />
<div align="center">
<!-- 说明:是要不是第一页,就显示首页,上一页;否则不显示 -->
<c:if test="${pageBean.currentPage!=1 }">
<a href="/customer_system/PageQueryServlet?currentPage=1">首页</a>
<a
href="/customer_system/PageQueryServlet?currentPage=${pageBean.currentPage!=1?pageBean.currentPage-1:1 }">上一页</a>
</c:if>
<!-- 参考百度的分页:左5 右4 -->
<!-- 情况一:总共页数小于或者等于10页 -->
<!-- 情况二:总共页数大于10页 -->
<!-- 此情况,考虑三种可能:(1)左边:[端点 ]begin=1,end=10(2)右边 :[端点]begin=${pageBean.totalPage-9} end=${pageBean.totalPage}
(3)中间 [普通情况]begin=${pageBean.currentPage-5>0?pageBean.currentPage-5:1 }
end=${pageBean.currentPage+4<pageBean.totalPage?pageBean.currentPage+4:pageBean.totalPage}
-->
<%-- <c:forEach var="i" begin="${pageBean.currentPage-5>1?pageBean.currentPage-5:1 }" end="${pageBean.currentPage+4<pageBean.totalPage?pageBean.currentPage+4: pageBean.totalPage}"> --%>
<c:choose>
<c:when test="${pageBean.totalPage<=10 }">
<c:forEach var="i" begin="1" end="${pageBean.totalPage}">
<c:if test="${pageBean.currentPage==i }">
<font color="red">${i }</font>
</c:if>
<c:if test="${pageBean.currentPage!=i }">
<a href="/customer_system/PageQueryServlet?currentPage=${i }">${i}</a>
</c:if>
</c:forEach>
</c:when>
<c:otherwise>
<c:choose>
<c:when test="${pageBean.currentPage<=10 }">
<c:forEach var="i"
begin="1"
end="10">
<c:if test="${pageBean.currentPage==i }">
<font color="red">${i }</font>
</c:if>
<c:if test="${pageBean.currentPage!=i }">
<a href="/customer_system/PageQueryServlet?currentPage=${i }">${i}</a>
</c:if>
</c:forEach>
</c:when>
<c:when test="${pageBean.currentPage+9>=pageBean.totalPage }">
<c:forEach var="i"
begin="${pageBean.totalPage-9}"
end="${pageBean.totalPage}">
<c:if test="${pageBean.currentPage==i }">
<font color="red">${i }</font>
</c:if>
<c:if test="${pageBean.currentPage!=i }">
<a href="/customer_system/PageQueryServlet?currentPage=${i }">${i}</a>
</c:if>
</c:forEach>
</c:when>
<c:otherwise>
<c:forEach var="i"
begin="${pageBean.currentPage-5>0?pageBean.currentPage-5:1 }"
end="${pageBean.currentPage+4<pageBean.totalPage?pageBean.currentPage+4:pageBean.totalPage}">
<c:if test="${pageBean.currentPage==i }">
<font color="red">${i }</font>
</c:if>
<c:if test="${pageBean.currentPage!=i }">
<a href="/customer_system/PageQueryServlet?currentPage=${i }">${i}</a>
</c:if>
</c:forEach>
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>
<!-- 说明:是要不是最后一页,就显示尾页,下一页;否则不显示 -->
<c:if test="${pageBean.currentPage!=pageBean.totalPage }">
<a
href="/customer_system/PageQueryServlet?currentPage=${pageBean.currentPage!=pageBean.totalPage?pageBean.currentPage+1:pageBean.totalPage }">下一页</a>
<a
href="/customer_system/PageQueryServlet?currentPage=${pageBean.totalPage }">尾页</a>
</c:if>
</div>
</body>
</html>
6.6.4 PageQueryServlet:分页查询web层
package com.zhku.jsj144.zk.web;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zhku.jsj144.zk.domain.PageBean;
import com.zhku.jsj144.zk.service.CustomersService;
public class PageQueryServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//解决乱码问题
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("text/html;charset=utf-8");
//分页查询客户信息
String currentPage=request.getParameter("currentPage");//当前页数
//获取分页信息
CustomersService customersService=new CustomersService();
//思考:如何只是单纯的把查询的信息带过去,就不能实现分页查询
//原因:每次查询都是一个CustomersList。是固定的,下一次则无法使用
//我们无法知道,每页记录数,总页数,总记录数,当前页数据,只是知道当前页数,所以无法实现分页查询
//结论:我们要一个PageBean,去封装我们要的数据:每页记录数,总页数,总记录数,当前页数,当前页数据。
//用于我们下一次查询时使用
PageBean pageBean=customersService.pageQuery(currentPage);
//保存分页查询信息,显示到分页查询信息页面
request.setAttribute("pageBean", pageBean);//保存分页查询信息
request.getRequestDispatcher("/pageQueryInfo.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
6.6.5 CustomersService :业务层(pageQuery(currentPage)方法)
详细看功能一代码实现,已经写好了
6.6.6 CustomersDao:dao接口层------------------------(selectPageList(start,pageRecord)方法)
详细看功能一代码实现,已经写好了
6.6.7 CustomersDaoImplement:dao结构层实现类------------------(selectPageList(start,pageRecord)方法)
详细看功能一代码实现,已经写好了
五、项目实现效果截图
(1)index.jsp
(2)添加客户信息页面addCustomer.jsp
(3)条件查询客户信息页面
(4)分页查询信息页面
(5)客户修改信息页面
(6)删除提示框跳出
项目详细代码资源:
本人的github项目地址
https://github.com/Forever99/customer_system