模拟百度实现分页
在中级项目中用到了很多分页显示数据的地方,今天特意把它整理出来。这是第一次写博客,写的不好的地方还请大家多多指教。
基于MVC模式,以显示用户信息为例来详细介绍分页。
基本思路:用户通过传页码到servlet,在调用pageBean中的setCurrentPage()设置当前页码,然后再调用dao层的getPageUser(bean)方法。
代码可直接使用,使用了数据库连接池c3p0,只要自己再添加一个UserDao即可。
- 实体类
一个是用户类(用户的详细信息)、一个是PageBean(对分页进行的一些限制)
package com.tang.entity;
/**
* User 实体类
* @author tang
*
*/
public class User {
//编号
private String id;
//用户名
private String username;
//密码
private String userpwd;
//家庭住址
private String address;
//联系电话
private String phone;
//email
private String email;
public User() { }
public User(String id, String username, String userpwd, String address,
String phone, String email) {
super();
this.id = id;
this.username = username;
this.userpwd = userpwd;
this.address = address;
this.phone = phone;
this.email = email;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpwd() {
return userpwd;
}
public void setUserpwd(String userpwd) {
this.userpwd = userpwd;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User [address=" + address + ", email=" + email + ", id=" + id
+ ", phone=" + phone + ", username=" + username + ", userpwd="
+ userpwd + "]";
}
}
PageBean 分页类
我使用的是mysql数据库,假设每页显示的数据为10,从数据库中查询出总的记录条数totalSize,那么显示数据的总页数pageCount就为totalSize/10或者totalSize/10+1.
package com.tang.entity;
import java.util.List;
/**
* 分页类
* @author tang
*
*/
public class PageBean {
//总记录条数
private int totalSize;
//当前页码
private int currentPage;
//总页数
private int pageCount;
//一页的数据
private List<User> userList;
//一页记录条数
private int SIZE=10;
//起始页
private int start;
//结束页
private int end;
public PageBean() { }
public PageBean(int totalSize, int currentPage, int pageCount,
List<User> userList, int sIZE, int start, int end) {
super();
this.totalSize = totalSize;
this.currentPage = currentPage;
this.pageCount = pageCount;
this.userList = userList;
SIZE = sIZE;
this.start = start;
this.end = end;
}
public int getTotalSize() {
return totalSize;
}
public void setTotalSize(int totalSize) {
this.totalSize = totalSize;
//当知道总记录数时就能算出总页数是多少
if(totalSize%SIZE==0){
this.pageCount=totalSize/SIZE;
}else{
this.pageCount=totalSize/SIZE+1;
}
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
//在这里设置起始页和结束页,如果总页数小于10,就只显示有几页,
//如果大于10,最开始显示的页码就是1-10
if(pageCount<=10){
start=1;
end=pageCount;
}else{
start=currentPage-5;
end=currentPage+4;
if(start<=0){
start=1;
end=10;
}
if(end>pageCount){
start=pageCount-10;
end=pageCount;
}
}
}
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
public int getSIZE() {
return SIZE;
}
public void setSIZE(int sIZE) {
SIZE = sIZE;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
@Override
public String toString() {
return "PageBean [SIZE=" + SIZE + ", currentPage=" + currentPage
+ ", end=" + end + ", pageCount=" + pageCount + ", start="
+ start + ", totalSize=" + totalSize + ", userList=" + userList
+ "]";
}
}
2、Dao层
Dao层的接口在这里我就省略了,只写出它的实现类。
package com.tang.dao.impl;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import com.tang.dao.UserDao;
import com.tang.entity.PageBean;
import com.tang.entity.User;
import com.tang.util.DBUtil;
/**
* userDao 的实现类
* @author tang
*
*/
public class UserDaoImpl implements UserDao{
/**
* 取得总的记录条数
*/
@Override
public int countUser(PageBean bean) throws SQLException {
QueryRunner run=new QueryRunner(DBUtil.dataSource);
String sql = "SELECT COUNT(0) FROM USER";
int n= Integer.parseInt(run.query(sql,new ScalarHandler()).toString());
bean.setTotalSize(n);
return n;
}
@Override
public PageBean getPageUser(PageBean bean) throws SQLException {
int size=bean.getSIZE();
int currentPage =bean.getCurrentPage();
QueryRunner run=new QueryRunner(DBUtil.dataSource);
//sql语句中limit??,前一个表示从第几条数据开始取,第二个参数是取几条
String sql = "SELECT * FROM USER limit ?,?";
Object param[]={(currentPage-1)*size,size};
List<User> userList=run.query(sql, new BeanListHandler(User.class), param);
bean.setUserList(userList);
return bean;
}
}
3、servlet
servlet直接调用dao层实现类的方法,本来我还写了一个服务层,但是因为业务逻辑是和dao层的一样的,所以这里我就直接调用了dao层。
package com.tang.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.tang.entity.PageBean;
import com.tang.entity.User;
public class ShowUserServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//设置响应编码,否则会出现乱码
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
//取得jsp页面传过来的页码
String page=request.getParameter("page");
PageBean bean=new PageBean();
//当前页的页码,如果页面传过来的值为null,那么默认为第一页
int currentPage;
if(page==null){
currentPage=1;
}else{
currentPage=Integer.parseInt(page);
}
//调用Dao层取得所有的用户信息
UserDao dao=new UserDaoImpl();
//获得数据库中的记录条数
int count=dao.countUser(bean);
//调用PageBean中的方法,设置记录总条数
bean.setTotalSize(count);
//设置当前页的页码
bean.setCurrentPage(currentPage);
//取得该页的用户数据
bean=dao.getPageUser(bean);
//将取得的指定页码的数据放到作用域中
request.setAttribute("pagebean", bean);
//派发到jsp页面显示数据
request.getRequestDispatcher("ShowUser.jsp").forward(request, response);
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
4、jsp页面显示数据
通过JSTL的迭代标签foreach,迭代输出作用域中的数据。
<%@ 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 'ShowUser.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 type="text/javascript"
src="bootstrap-3.3.7-dist/js/jquery-2.1.1.js"></script>
<script type="text/javascript"
src="bootstrap-3.3.7-dist/js/bootstrap.js"></script>
<link rel="stylesheet" href="bootstrap-3.3.7-dist/css/bootstrap.css" />
</head>
<body>
<div class="container">
<table class="table table-striped">
<caption>
用户信息表
</caption>
<thead>
<tr>
<th>
编号
</th>
<th>
用户名
</th>
<th>
密码
</th>
<th>
地址
</th>
<th>
电话
</th>
<th>
邮箱
</th>
</tr>
</thead>
<tbody id="userInfo">
<c:forEach items="${pagebean.userList}" var="obj">
<tr>
<td>${obj.id}</td>
<td>${obj.username}</td>
<td>${obj.userpwd}</td>
<td>${obj.address}</td>
<td>${obj.phone}</td>
<td>${obj.email}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<br><br>
<center>
<c:if test="${pagebean.currentPage!=1}">
<a href="ShowUserServlet?page=${pagebean.currentPage-1}">上一页</a>
</c:if>
<c:forEach begin="${pagebean.start}" end="${pagebean.end}" varStatus="i">
<a href="ShowUserServlet?page=${i.index}" class="px">${i.index } </a>
</c:forEach>
<c:if test="${pagebean.currentPage!=pagebean.pageCount}">
<a href="ShowUserServlet?page=${pagebean.currentPage+1}">下一页</a>
</c:if>
</center>
</body>
</html>
5、效果截图