- 页面中的数据有:
结果集:通过 SQL 语句查询得来的——**List**
- 分页条中的数据有:
当前页:用户传递到后台——**currentPage**
总页数:计算的来——**totalPage**
上一页:计算的来——**prePage**
下一页:计算的来——**nextPage**
尾页:计算的来(总页数)——**lastPage**
页面大小(即每一页显示的条数):用户传递到后台——**count**
总条数:通过 SQL 语句查询得来的——**totalCount**
可以发现页面功能中需要用到的数据有两个是需要通过 SQL 语句查询得来的:一个是页面中显示的数据 List ,另一个是数据的总条数 totalCount,分别对应以下两条 SQL 语句:
SELECT * FROM student LIMIT #{param1}, #{param2}
SELECT COUNT(*) FROM student
通过计算得到的数据有:
- 总页数:totalPage
总页数 = 总条数 % 页面大小 == 0 ? 总条数 / 页面大小 : 总条数 / 页面大小 + 1
- 上一页:prePage
上一页 = 当前页 - 1 > = 1 ? 当前页 - 1 : 1
- 下一页:nextPage
下一页 = 当前页 + 1 <= totalPage ? 当前页 + 1 : totalPage
- 尾页:lastPage
尾页 = 总条数 % 页面大小 == 0 ? 总条数 - 页面大小 : 总条数 - 总条数 % 页面大小
用户传递的数据:
- 当前页:currentPage
- 页面大小:count
所有我们可以创建一个 Page 工具类备用:
public class Page {
int start; // 开始数据的索引
int count; // 每一页的数量
int total; // 总共的数据量
/**
-
提供一个构造方法
-
@param start
-
@param count
*/
public Page(int start, int count) {
super();
this.start = start;
this.count = count;
}
/**
-
判断是否有上一页
-
@return
*/
public boolean isHasPreviouse(){
if(start==0)
return false;
return true;
}
/**
-
判断是否有下一页
-
@return
*/
public boolean isHasNext(){
if(start==getLast())
return false;
return true;
}
/**
-
计算得到总页数
-
@return
*/
public int getTotalPage(){
int totalPage;
// 假设总数是50,是能够被5整除的,那么就有10页
if (0 == total % count)
totalPage = total /count;
// 假设总数是51,不能够被5整除的,那么就有11页
else
totalPage = total / count + 1;
if(0==totalPage)
totalPage = 1;
return totalPage;
}
/**
-
计算得到尾页
-
@return
*/
public int getLast(){
int last;
// 假设总数是50,是能够被5整除的,那么最后一页的开始就是45
if (0 == total % count)
last = total - count;
// 假设总数是51,不能够被5整除的,那么最后一页的开始就是50
else
last = total - total % count;
last = last<0?0:last;
return last;
}
/* getter and setter */
}
前台实现分页设计
首先我们在前台需要完成我们分页条的设计,这里可以直接引入 Bootstrap 来完成:
上面是使用 Bootstrap 实现一个分页条的简单例子,如果不熟悉的童鞋可以去菜鸟教程中查看:点这里
简单版本的分页条
为了便于理解,我们先来实现一个简单版本的分页条吧:
- 首页超链:指向了 start 为 0 的首页
-
«
- 上一页超链:
-
‹
- 下一页超链:
-
›
- 最后一页超链:指向了最后一页
-
»
- 中间页:
<c:forEach begin=“0” end=“${page.totalPage-1}” varStatus=“status”>
-
</c:forEach>
- 所以写完看起来会是这样子的:
-
«
-
‹
<c:forEach begin=“0” end=“${page.totalPage-1}” varStatus=“status”>
-
</c:forEach>
-
›
-
»
- 存在的问题:
① 没有边界判断,即在首页仍然可以点击前一页,不符合逻辑也影响用户体验
② 会显示完所有的分页,即如果 totalPage 有50页,那么分页栏将会显得特别长,影响体验
改良版本的分页条
1.写好头和尾
…
2.写好
«
‹
这两个功能按钮使用
<c:if>
标签来增加边界判断,如果没有前面的页码了则设置为disable状态«
‹
再通过 JavaScrip 代码来完成禁用功能:
3.完成中间页码的编写
<c:forEach begin=“0” end=“${page.totalPage-1}” varStatus=“status”>
<c:if test=“${status.countpage.count-page.start<=30 && status.countpage.count-page.start>=-10}”>
<a
href=“?page.start=${status.index*page.count}”
<c:if test=“${status.index*page.count==page.start}”>class=“current”</c:if>
${status.count}
</c:if>
</c:forEach>
从
0
循环到page.totalPage - 1
,varStatus
相当于是循环变量-
status.count 是从1开始遍历
-
status.index 是从0开始遍历
-
**要求:**显示当前页码的前两个和后两个就可,例如当前页码为3的时候,就显示 1 2 3(当前页) 4 5 的页码
-
理解测试条件:
-10 <= 当前页*每一页显示的数目 - 当前页开始的数据编号 <= 30
- 只要理解了这个判断条件,其他的就都好理解了
- 注意: 测试条件是需要根据项目的需求动态改变的,不是万能的!
后台中的分页
首页在项目中引入上面提到的 Page 工具类,然后我们在 DAO 类中使用 LIMIT 关键字来查询数据库中的信息:
public List list() {
return list(0, Short.MAX_VALUE);
}
public List list(int start, int count) {
List students = new ArrayList<>();
String sql = “SELECT * FROM student ORDER BY student_id desc limit ?,?”;
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql)) {
ps.setInt(1, start);
ps.setInt(2, count);
// 获取结果集…
} catch (SQLException e) {
e.printStackTrace();
}
return students;
}
在 Servlet 中获取分页参数并使首页显示的 StudentList 用 page 的参数来获取:
// 获取分页参数
int start = 0;
int count = 10;
try {
start = Integer.parseInt(req.getParameter(“page.start”));
count = Integer.parseInt(req.getParameter(“page.count”));
} catch (Exception e) {
}
Page page = new Page(start, count);
List students = studentDAO.list(page.getStart(), page.getCount());
…
// 共享数据
req.setAttribute(“page”, page);
req.setAttribute(“students”, students);
以上即可完成分页功能,但这是基于 Servlet 的版本,在之前写过的项目(学生管理系统(简易版))中实际的使用了这种方法,感兴趣的可以去看一下。
SSM 中的分页
(SQLException e) {
e.printStackTrace();
}
return students;
}
在 Servlet 中获取分页参数并使首页显示的 StudentList 用 page 的参数来获取:
// 获取分页参数
int start = 0;
int count = 10;
try {
start = Integer.parseInt(req.getParameter(“page.start”));
count = Integer.parseInt(req.getParameter(“page.count”));
} catch (Exception e) {
}
Page page = new Page(start, count);
List students = studentDAO.list(page.getStart(), page.getCount());
…
// 共享数据
req.setAttribute(“page”, page);
req.setAttribute(“students”, students);
以上即可完成分页功能,但这是基于 Servlet 的版本,在之前写过的项目(学生管理系统(简易版))中实际的使用了这种方法,感兴趣的可以去看一下。
SSM 中的分页