1、分页:
原理:利用sql语句中的方言:limit x , y 从x行开始查,查y行
优点:每次只查询部分,不用查询所有
2、数据的传递:
分页数据们需要在各层之间来回的传递!
为了提升效率,将所有分页数据装进JavaBean中,起名为分页bean。
构成一个JavaBean对象,数据传递时传输该对象即可。
PageBean:
public class PageBean<T> {
private int pc;
private int tp;
private int tr;
private int ps;
private List<T> beanList;
private String url;
}
3、页面数据:
页面数据都是由Servlet传递过来的。
Servlet需要的数据:
当前面:pageCode,pc;
pc:1)如果页面没有传递当前页码,那么Servlet默认是第一页,
2)按页面传递的页码为准!
总页数:totalPages,tp
tp:总记录数(tr)/每页记录数(ps)
总记录数:totalRecored,tr
tr:dao来获取,select count(*) from t_customer;
每页记录数:业务数据或叫系统数据!10行! (ps)
当前页数据:beanList
url //用来代表超链接后参数条件
4、分页在各层中的处理
页面:给出分页相关的所有链接
Servlet:创建PageBean对象,给PageBean所有属性赋值,传递给页面。
servlet需要给DAO传递 pc 、ps
service:略
Dao:
tr: select count(*)...
beanList:select * from t_customer limit x.y; (从x行开查询,查y行)
5、显示页码列表
1)需要计算出页码列表的起始位begin和终止位end,
2)动态显示出从begin到end范围内的页码数字
3)对页码加上超链接
1 2 3 4 5 (6) 7 8 9 10 括号内为当前页
需要设置:
1)最多显示多少个页码! 现定为10;
2)当前页,在页码列表中的位置,定为6;
页码列表计算:
思路:使用当前页码来推算出前后页
需要两样数据:
begin
end
10 11 12 13 14 (15) 16 17 18 19
需要使用pc来推算出begin和end
begin = pc – 5
end = pc + 4
计算公式:
1)总页数 <= 10(列表长度),那么begin=1,end=总页数
2)总页数 > 10
使用公式计算;begin=pc-5, end=pc + 4;
头溢出:当begin<1时,让begin=1
尾溢出:当end>${tp}时,让end=${tp}
6、分页之查询条件丢失问题
问题介绍:当使用多条件查询后,再点击第 2 页时,第 2 页超链接条件会发生丢失。
为了正常使用,在超链接中要保留参数
解决:1)把条件以字符串的形式保存到PageBean的url中。
2)在servlet中截取字符串。
问题:post请求不能传递参数,导致参数不能直接获取
解决:将post改为get
问题:改为get后需要手动处理get请求编码问题。post方式在BaseServlet中已被自动处理过。
解决:手动挨个设置get方法携带的参数。
url中截去pc的目的: pc是个变量,不能被固定。
servlet
1)
public String findAll(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int pc = getPc(request);
int ps = 10;
PageBean<Customer> pb = customerService.findAll(pc,ps);
pb.setUrl(getUrl(request));
request.setAttribute("pb", pb);
return "f:/list.jsp";
}
private int getPc(HttpServletRequest request){
String value = request.getParameter("pc");
if(value == null || value.trim().isEmpty()){
return 1;
}
return Integer.parseInt(value);
}
2)
public String query(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Customer criteria = CommonUtils.toBean(request.getParameterMap(), Customer.class);
criteria = encoding(criteria);
int pc = getPc(request);
int ps = 10;
PageBean<Customer> pb = customerService.query(criteria,pc,ps);
pb.setUrl(getUrl(request));
request.setAttribute("pb", pb);
return "f:/list.jsp";
}
private Customer encoding(Customer criteria) throws UnsupportedEncodingException {
String cname = criteria.getCname();
String gender = criteria.getGender();
String cellphone = criteria.getCellphone();
String email = criteria.getEmail();
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);
}
if(cellphone != null && !cellphone.trim().isEmpty()){
cellphone = new String (cellphone.getBytes("ISO-8859-1"),"utf-8");
criteria.setCellphone(cellphone);
}
if(email != null && !email.trim().isEmpty()){
email = new String (email.getBytes("ISO-8859-1"),"utf-8");
criteria.setEmail(email);
}
return criteria;
}
/**
* 截取url
* /项目名/Servlet路径?参数字符串
* @param request
* @return
*/
private String getUrl(HttpServletRequest request){
String contextPath = request.getContextPath();
String servletPath = request.getServletPath();
String queryString = request.getQueryString();
if(queryString.contains("&pc=")){
int index = queryString.lastIndexOf("&pc=");
queryString = queryString.substring(0,index);
}
return contextPath + servletPath + "?" + queryString;
}
CustomerDao
1)
public PageBean<Customer> findAll(int pc, int ps){
try{
PageBean<Customer> pb = new PageBean<Customer>();
pb.setPc(pc);
pb.setPs(ps);
String sql = "select count(*) from t_customer";
Number num = (Number)qr.query(sql, new ScalarHandler());
int tr = num.intValue();
pb.setTr(tr);
sql = "select * from t_customer limit ?,?";
List<Customer> beanList = qr.query(sql,
new BeanListHandler<Customer>(Customer.class),
(pc-1)*ps,ps);
pb.setBeanList(beanList);
return pb;
}catch(SQLException e){
throw new RuntimeException(e);
}
}
2)
public PageBean<Customer> query(Customer criteria, int pc, int ps) {
try{
PageBean<Customer> pb = new PageBean<Customer>();
pb.setPc(pc);
pb.setPs(ps);
StringBuilder cntSql = new StringBuilder("select count(*) from t_customer");
StringBuilder whereSql = new StringBuilder(" where 1=1");
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(gender != null && !gender.trim().isEmpty()){
whereSql.append(" and gender=?");
params.add(gender);
}
String cellphone = criteria.getCellphone();
if(cellphone != null && !cellphone.trim().isEmpty()){
whereSql.append(" and cellphone like ?");
params.add("%" + cellphone + "%");
}
String email = criteria.getEmail();
if(email != null && !email.trim().isEmpty()){
whereSql.append(" and email like ?");
params.add("%" + email + "%");
}
Number num = (Number) qr.query(cntSql.append(whereSql).toString(),
new ScalarHandler(),
params.toArray());
int tr = num.intValue();
pb.setTr(tr);
StringBuilder sql = new StringBuilder("select * from t_customer");
StringBuilder limitSql = new StringBuilder(" 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);
}
}
list.jsp
<body>
<h3 align="center">客户列表</h3>
<table border="1" width="70%" align="center">
<tr>
<th>客户姓名</th>
<th>性别</th>
<th>生日</th>
<th>手机</th>
<th>邮箱</th>
<th>描述</th>
<th>操作</th>
</tr>
<c:forEach items="${pb.beanList }" var="cstm">
<tr>
<td>${cstm.cname }</td>
<td>${cstm.gender }</td>
<td>${cstm.birthday }</td>
<td>${cstm.cellphone }</td>
<td>${cstm.email }</td>
<td>${cstm.description }</td>
<td>
<a href="<c:url value='/CustomerServlet?method=loadForEdit&cid=${cstm.cid }'/>">编辑</a>
<a href="<c:url value='/CustomerServlet?method=delete&cid=${cstm.cid }'/>">删除</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>
<%-- 计算页码 --%>
<c:choose>
<%-- 1)总页数 <= 10(列表长度),那么begin=1,end=总页数 --%>
<c:when test="${pb.tp <= 10 }">
<c:set var="begin" value="1" />
<c:set var="end" value="${pb.tp }" />
</c:when>
<%-- 2)总页数 > 10 ,通过公式计算出begin, end --%>
<c:otherwise>
<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="&pc=${pb.tp } ">尾页</a>
</center>
</body>