目录
为什么要使用分页去显示数据?
当我们在浏览器看一堆很长的列表时,滚动条一滑动,很容易找不到位置,当数据量庞大时,数据库的加载和浏览器解析请求时变的很慢。
思路
- 确定每页需要的数据数量。
- 计算数据可以显示的总页数
- 实现获取指定页码的数据记录
实现效果
步骤
(1)创建PageUntil分页工具类
Constats类用来存放常量,固定不变的值,如每页的数据量
(2)声明对应的属性进行封装
//当前页数
private int pageIndex;
//每页数据量
private int pageSize = Constats.PAGE_SIZE;
//总数据量
private int pageTotalCount;
//总页数
private int pageTotal;
//存储列表分页数据
private List<T> listdata;
public List<T> getListdata() {
return listdata;
}
public void setListdata(List<T> listdata) {
this.listdata = listdata;
}
public int getPageIndex() {
return pageIndex;
}
public void setPageIndex(int pageIndex) {
this.pageIndex = pageIndex;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getPageTotalCount() {
return pageTotalCount;
}
public void setPageTotalCount(int pageTotalCount) {
this.pageTotalCount=pageTotalCount;
}
public int getPageTotal() {
return pageTotal;
}
public void setPageTotal(int pageTotal) {
this.pageTotal = pageTotal;
}
(3)计算数据可以显示的总页数
public void setPageTotalCount(int pageTotalCount) {
//当设置总数据量时,计算总页数=总数据量/每页数据量
if (pageTotalCount % pageSize == 0) {
//当总数据量可以除尽: 是偶数时
pageTotal = pageTotalCount / pageSize;
} else {
//当总数据量除不尽,可能有余数(总页数+1)
pageTotal = pageTotalCount / pageSize + 1;
}
}
更改pageTotalCount的set方法,当获得总数据量时,可以根据总数据量/每页数据量,计算出总页数。
(4)获取页码数据记录
即使要分页,每一个都不一样,那么怎么对应sql语句去查询不同的语句呢?
select * from student LIMIT 0,5; //根据LIMIT分页查询 前五行
select * from student LIMIT 5,5; //忽略前五行,查找五行
问题
-LIMIT前面的参数是忽略几行开始查,我们在数据库中每一页LIMIT前面的参数都会变化,那怎么去计算呢?我们可以根据当前页数的变化去计算忽略行数。
select * from student LIMIT pageIndex=(pageIndex-1)*5,5;
(5)servlet填充对象内容
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
PageUntil<Student> pageUntil = new PageUntil<>();
//获取总数据量
int pageTotal = service.selectPageTotal();
pageUntil.setPageTotalCount(pageTotal);
//当前页数由前台去获取
String pageIndex = req.getParameter("pageIndex");
if (pageIndex == null) {
pageIndex = "1";
}
//当前页数赋给set
pageUntil.setPageIndex(Integer.parseInt(pageIndex));
//当前页数和每页数据量去查找数据
listStudentsPage = service.listStudentByPage(pageUntil.getPageIndex(),
pageUntil.getPageSize());
//将查找的数据存放在集合里
pageUntil.setListdata(listStudentsPage);
req.setAttribute("pageUtil", pageUntil);
}
selectPageTotal()方法获取总数据量根据sql语句返回总行数即可,这里就不写了
Service层根据参数查找数据
public List<Student> listStudentByPage(int pageIndex, int pageSize) {
return studentDao.listStudentsByPage((pageIndex-1)*5,pageSize);
}
Dao层访问数据库
public List<Student> listStudentsByPage(int pageIndex, int pageSize) {
Connection con=getConnection();
PreparedStatement pres=null;
ResultSet rs=null;
List<Student> students=null;
String sql="select * from student LIMIT ?,?";
try {
pres=con.prepareStatement(sql);
pres.setInt(1,pageIndex);
pres.setInt(2,pageSize);
rs=pres.executeQuery();
students=new ArrayList<>();
while(rs.next())
{
Student stu=new Student();
stu.setId(rs.getInt("id"));
stu.setName(rs.getString("name"));
stu.setAge(rs.getInt("age"));
stu.setGender(rs.getString("gender"));
stu.setPhone(rs.getString("phone"));
stu.setAddress(rs.getString("address"));
students.add(stu);
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
closeConnection(rs,pres,con);
}
return students;
}
(6)设置页面
当我们后台处理完毕后,当前页数和具体操作都需要靠前台来设置。
<div>
<a href="/Student?op=list&pageIndex=1">首页</a>
<a href="/Student?op=list&pageIndex=${pageUtil.pageIndex-1<1?pageUtil.pageIndex:pageUtil.pageIndex-1}">上一页</a>
<a href="/Student?op=list&pageIndex=${pageUtil.pageIndex+1>pageUtil.pageTotal?pageUtil.pageIndex:pageUtil.pageIndex+1}">下一页</a>
<a href="/Student?op=list&pageIndex=${pageUtil.pageTotal}">尾页</a>
当前第 <strong>${pageUtil.pageIndex}</strong>页,共有 <strong>${pageUtil.pageTotal}</strong>页
</div>
启动Servlet的地址自己设置即可,我用的是Student?op=list
注意: 当上一页已经到头了,继续点的时候我们会利用三目运算符做一个判断,如果当前页数小于1的话,就停留在当前页,否则就继续-1,下一页到头的设置同理。