分页
1、分页
首页 上一页 1 2 3 4 下一页 尾页 go
分页的优点:只查询一页,不用查询所有页
2、分页数据
页面的数据都是由Servlet传递来的。
Servlet
当前页:pageCode,pc;
pc:如果页面没有传递当前页码,那么Servlet默认是第一页,否则按页面传递的为准
总页数:totalPage,tp
tp:总记录数/每页记录数
总记录数:totalRecord:tr
tr:dao来获取,select count(*) from t_customer
每页记录数:业务数据或叫系统数据 ps
当前页数据:beanList,bl
url
3、分页Bean的设计
这些分页数据总是要在各层之间来回的传递
我们把这些分页数据封装到一个javaBean中,它就叫分页Bean,例如PageBean
4、分页在各层中的处理
页面:给出分页相关的链接
页面需要给Servlet传递什么:可能传递pc
servlet:创建PageBean对象,给PageBean所有的属性赋值,然后传递给页面
Servlet需要给dao传递,当前页码pc、ps
service:
dao
tr:select count(*) from t_customer
beanlist:select * from t_customer limit x,y;
5、显示分页页码列表
1 2 3 4 5
最多显示多少个页码。定为10
当前页,在页码列表中的位置,定为5
只需要当前页码来定出来页码列表
定下来页码列表只需要两样数据
begin
end
需要使用pc来推算出begin和end
begin = pc-5
end = pc+4
计算公式
如果总页数<=10(列表长度) 那么begin=1,end=总页数
使用公式计算:begin=pc-5,end=pc+4;
头溢出:当begin<1时让begin=1
尾溢出:当end>${tp}时,让end=${tp}
6、在超链接中要保留参数
当使用多条件查询后,然后在点击第2页时,这个第2页超链接没有条件了,所以会丢失条件,所以我们需要在页面上的所有链接都要保存条件。
要把条件以一个字符串的形式保存到PageBean的url中 。任务交给Servlet
domain pageBean
public class PageBean<T> {
private int pc;//当前页面 pageCode
// private int tp;//总页数 totalPage
private int tr;//总记录数totalRecord
private int ps;//每页记录数pageSize
private List<T> beanList;//当前页的记录
private String url;//就是url后的条件
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getPc() {
return pc;
}
public void setPc(int pc) {
this.pc = pc;
}
/**
* 计算总页数
* @return
*/
public int getTp() {
//通过总记录数和每页记录数来计算总页数
int tp = tr/ps;
return tr%ps==0? tp:tp+1;
}
// public void setTp(int tp) {
// this.tp = tp;
// }
public int getTr() {
return tr;
}
public void setTr(int tr) {
this.tr = tr;
}
public int getPs() {
return ps;
}
public void setPs(int ps) {
this.ps = ps;
}
public List<T> getBeanList() {
return beanList;
}
public void setBeanList(List<T> beanList) {
this.beanList = beanList;
}
}
CustomerDao 新增
public PageBean<Customer> findAll(int pc, int ps) {
try{
/* 1、创建pageBean对象pb
* 2、设置pb的pc和ps
* 3、得到tr,设置给pb
* 4、得到beanList,设置给pb
* 5、返回pb
*/
PageBean<Customer> pb = new PageBean<Customer>();
pb.setPc(pc);
pb.setPs(ps);
// 得到tr
String sql = "select count(*) from t_customer ";
Number num = (Number)qr.query(sql, new ScalarHandler());
int tr = num.intValue();
pb.setTr(tr);
//得到beanList
sql = "select * from t_customer order by cname limit ?,? ";
List<Customer> beanList = qr.query(sql,
new BeanListHandler<Customer>(Customer.class),
(pc-1)*ps,ps);
pb.setBeanList(beanList);
System.out.println(pb);
return pb;
} catch(SQLException e){
throw new RuntimeException(e);
}
}
public PageBean<Customer> query(Customer criteria, int pc, int ps) {
try{
/*
* 1、创建PageBean对象
* 2、设置已有的属性,pc和ps
* 3、得到tr
* 4、得到beanList
*/
/*
* 创建pb,设置已有属性
*/
PageBean<Customer> pb = new PageBean<Customer>();
pb.setPc(pc);
pb.setPs(ps);
/*
* 得到tr
*/
/*
* 1、给出sql语句的前半部 用废条件占where 可以在以后直接用and
*/
StringBuilder cntSql = new StringBuilder("select count(*) from t_customer ");
StringBuilder whereSql = new StringBuilder(" where 1=1 ");
/*
* 2、判断条件,完成向sql中追加where子句
*/
/*
* 3、创建一个ArrayList,用来装载参数值
*/
List<Object> params = new ArrayList<Object>();
String cname = criteria.getCname();
if(cname!=null && !cname.trim().isEmpty()){
//模糊查询 更全面
whereSql.append(" and cname like ? ");
params.add("%"+cname+"%");
}
String gender = criteria.getGender();
if(cname!=null && !gender.trim().isEmpty()){
whereSql.append(" and gender=? ");
params.add(gender);
}
/*
* select count(*) ... + where 子句
*/
Number num = (Number) qr.query(cntSql.append(whereSql).toString(),
new ScalarHandler(),params.toArray());
int tr = num.intValue();
pb.setTr(tr);
/*
* 得到beanList
*/
StringBuilder sql = new StringBuilder("select * from t_customer ");
//查询beanList这一步,需要给出limit子句
StringBuilder limitSql = new StringBuilder(" limit ?,? ");
//params中需要给出limit后两个问号对应的值
params.add((pc-1)*ps);
params.add(ps);
//执行
List<Customer> beanList = qr.query(sql.append(whereSql).append(limitSql).toString(),
new BeanListHandler<Customer>(Customer.class),
params.toArray());
pb.setBeanList(beanList);
return pb;
} catch(SQLException e){
throw new RuntimeException(e);
}
}
CustomerService
// public List<Customer> query(Customer criteria) {
// return customerDao.query(criteria);
// }
public PageBean<Customer> findAll(int pc, int ps) {
return customerDao.findAll(pc,ps);
}
public PageBean<Customer> query(Customer criteria, int pc, int ps) {
return customerDao.query(criteria, pc,ps);
}
CustomerServlet
public String findAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
*1、获取页面传递的pc
*2、给定ps的值
*3、使用pc和ps调用service方法,得到pageBean,保存到request域
*4、转发到list.jsp
*/
/*
* 1、得到pc
* 如果pc参数不存在,说明pc=1
* 如果pc参数存在,需要转换成int类型即可
*/
int pc = getPc(req);//得到pc
int ps = 10;//给定ps的值 每页10记录
PageBean<Customer> pb = customerService.findAll(pc,ps);//传递pc,ps给service,得到pageBean
//设置url
pb.setUrl(getUrl(req));
req.setAttribute("pb", pb);//保存到request域
return "f:/list.jsp";
}
/**
* 获取pc
*/
private int getPc(HttpServletRequest req){
String value = req.getParameter("pc");
if(value == null || value.trim().isEmpty()){
return 1;
}
return Integer.parseInt(value);
}
public String query(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
* 0、把条件封装到Customer对象中
* 1、得到pc
* 2、给定ps
* 3、使用pc和ps,以及条件对象,调用service方法得到PageBean
* 4、把PageBean保存到request域中
* 5、转发到list.jsp
*/
//获取查询条件
Customer criteria = CommonUtils.toBean(req.getParameterMap(), Customer.class);
/*
* 处理GET请求方式编码问题
*/
//criteria = encoding(criteria);
int pc = getPc(req);//得到pc
int ps = 10;//给定ps的值,每页10行记录
PageBean<Customer> pb = customerService.query(criteria,pc,ps);
//得到url保存到pb中
pb.setUrl(getUrl(req));
req.setAttribute("pb", pb);
return "f:/list.jsp";
}
/**
* 处理两样
* @throws UnsupportedEncodingException
*/
private Customer encoding(Customer criteria) throws UnsupportedEncodingException {
String cname = criteria.getCname();
String gender = criteria.getGender();
if(cname != null && !cname.trim().isEmpty()){
cname = new String (cname.getBytes("ISO-8859-1"),"UTF-8");
criteria.setCname(cname);
}
if(gender != null && !gender.trim().isEmpty()){
gender = new String (gender.getBytes("ISO-8859-1"),"UTF-8");
criteria.setGender(gender);
}
return criteria;
}
/**
* 截取url
* /项目名/Servlet路径?参数字符串
* @param req
* @return
*/
private String getUrl(HttpServletRequest req){
String contextPath = req.getContextPath();//获取项目名
String servletPath = req.getServletPath();//获取servletPath 即/CustomerServlet
String queryString = req.getQueryString();//获取问号之后的参数部分
//判断参数中是否包含pc这个参数 如果包含就截取掉这一部分
if(queryString.contains("&pc=")){
int index = queryString.lastIndexOf("&pc=");
queryString = queryString.substring(0,index);
}
return contextPath +servletPath + "?" +queryString;
}
query.jsp
<body>
<%--保留传递的参数使用get方法 --%>
<form action="<c:url value='/CustomerServlet'/>" method="get">
<input type="hidden" name="method" value="query" />
<table border="0" align="center" width="40%" style="margin-left:100px">
<tr>
<td width="100px">客户名称</td>
<td width ="40%" >
<input type="text" name="cname"/>
</td>
</tr>
<tr>
<td >客户性别</td>
<td>
<select name="gender">
<option value="男">男</option>
<option value="女">女</option>
</select>
</td>
</tr>
</table>
<input type="submit" value="提交" style="margin-left: 100px;"/>
</form>
</body>
list.jsp
<body>
<h3 align="center">客户列表</h3>
<table border="1" width="70%" align="center">
<tr>
<th>客户姓名</th>
<th>性别</th>
</tr>
<%--
要遍历PageBean的beanList这个集合
--%>
<c:forEach items="${pb.beanList}" var="cstm">
<tr>
<td>${cstm.cname }</td>
<td>${cstm.gender }</td>
<td>
<a href="<c:url value='/CustomerServlet?method=preEdit&cid=${cstm.cid }'/>">编辑</a>
<a href="<c:url value='/msg.jsp'/>">删除</a>
</td>
</tr>
</c:forEach>
</table>
<br/>
<%--
给出分页相关的链接
--%>
<center>
第${pb.pc}页/共${pb.tp}页
<a href="${pb.url }&pc=1">首页</a>
<c:if test="${pb.pc>1 }">
<a href="${pb.url }&pc=${pb.pc-1 }">上一页</a>
</c:if>
<%--计算begin,end --%>
<c:choose>
<%-- 如果总页数不足10页,那么把所有的页数都显示出来 --%>
<c:when test="${pb.tp<=10 }">
<c:set var="begin" value="1"/>
<c:set var="end" value="${pb.tp }"/>
</c:when>
<c:otherwise>
<%--当总页数大于10时,通过公式计算出begin和end --%>
<c:set var="begin" value="${pb.pc-5 }"/>
<c:set var="end" value="${pb.pc+4 }"/>
<%--头溢出 --%>
<c:if test="${begin<1 }">
<c:set var="begin" value="1"/>
<c:set var="end" value="10"/>
</c:if>
<%--尾溢出 --%>
<c:if test="${end>pb.tp }">
<c:set var="begin" value="${pb.tp-9}"/>
<c:set var="end" value="${pb.tp }"/>
</c:if>
</c:otherwise>
</c:choose>
<%--循环遍历页码列表 --%>
<c:forEach var="i" begin="${begin}" end="${end}">
<c:choose>
<c:when test="${i eq pb.pc }">
[${i }]
</c:when>
<c:otherwise>
<a href="${pb.url }&pc=${i }">[${i }]</a>
</c:otherwise>
</c:choose>
</c:forEach>
<c:if test="${pb.pc<pb.tp }">
<a href="${pb.url }&pc=${pb.pc+1 }">下一页</a>
</c:if>
<a href="${pb.url }&pc=${pb.tp }">尾页</a>
</center>
</body>