页面数据的分页功能实现
分页属于一个业务,里面包含了多个逻辑单元:
每一页的数据中包含了:
class PageBean{
当前页数;(int currentPage)
总页数;(int totalPage)
总记录数;(int totalSize)
每页记录数;(int pageSize)
该页的数据对象集合(如:List<Student>类)。
}
物理分页(真分页):
来数据库查询的时候,只查一页的数据就返回,需要第一页就查询第一页,第二页就查询第二页。
优点:内存中的数据量不会太大。
缺点:需要频繁的访问数据库
1.当前页数(int currentPage)
从JSP界面中获取,通过 request 域传到Servlet中接收。
// 1.获取需要当前页码数
//int currentPage
int currentPage = Integer.parseInt(request.getParameter("currentPage"));
2.总记录数(int totalPage)
通过数据库语句和DButils数据库操作类获取总记录数。
//获取总记录数
public int findCount() throws SQLException {
QueryRunner runner = new QueryRunner(JDBCutil02.getDataSource());
String sql = "select count(*) from stu";
//用于处理平均值,总的个数
Long result = (Long) runner.query(sql,new ScalarHandler());
return result.intValue();
}
3.总页数(int totalPage)
对总记录数(int totalPage)进行相应的运算,得到总页数
//如果总记录数对每页显示页数(pageSize)取余,能整除,则用count/pageSize,否则则用(count/pageSize) + 1
//总页数:201,每页数:5 201 % 5 = 1。 201 % 5 ==0 ? 201 / 5 : 201 / 5 + 1
pageBean.setTotalPage(count % pageSize == 0 ? count/pageSize : (count/pageSize) + 1);//总页数
4.每页记录数(int pageSize)
在Dao接口中设置一个常量,作为固定显示的每页记录数,或者也可以在调用方法的时候定义。
int PAGE_SIZE = 5;//一页显示多少条数据
5.查询该页的数据对象集合(List<Student>)
Select * from stu limit 5 offset 2 (或 Select * from stu limit 2,5)
//查询表stu的前5条数据,从表的第2行开始,offset(偏移量)
public List<Student> findStudentByPage(int currentPage) throws SQLException {
int PAGE_SIZE = 5;//一页显示多少条数据
QueryRunner runner = new QueryRunner(JDBCutil02.getDataSource());
String sql = "select * from stu limit ? offset ?";
//@param currentPage(当前页)
//第一个问号,代表一页返回多少条记录,第二个问号,跳过前面的多少条记录,即是从第几行数据开始
//5 0 --- 第一页 (1-1)* 5
//5 5 --- 第二页 (2-1)* 5
//5 10 --- 第三页 (3-1)* 5
return runner.query(sql,new BeanListHandler<Student>(Student.class),PAGE_SIZE,(currentPage-1)*PAGE_SIZE);
}
6.JSP页面显示(list_page.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>学生列表页面</title>
<script type="text/javascript">
function doDelete(sid){
//如果弹出的对话框,用户点击确定时,请求Servlet
var flag = confirm("是否确定删除?");//根据确定或者取消返回true或者false
if (flag){
//表明点了确定,访问Servlet.
//在当前标签页上打开指向的超链接
//window.location.href="DeleteServlet?sid=" + sid;
//或者是
location.href="DeleteServlet?sid=" + sid;
}
}
</script>
</head>
<body>
<form action="SearchStudentServlet" method="post">
<table border="1" width="700">
<tr>
<td colspan="8">
按姓名查询:<input type="text" name="sname">
按性别查询:
<select name="sgender">
<option value="">--请选择--</option>
<option value="男">男</option>
<option value="女">女</option>
</select>
<input type="submit" value="查询">
<a href="add.jsp">添加</a>
</td>
</tr>
<tr align="center">
<td>编号</td>
<td>姓名</td>
<td>性别</td>
<td>电话</td>
<td>生日</td>
<td>爱好</td>
<td>简介</td>
<td>操作</td>
</tr>
<c:forEach items="${pageBean.list}" var="stu">
<tr align="center">
<td>${stu.sid}</td>
<td>${stu.sname}</td>
<td>${stu.gender}</td>
<td>${stu.phone}</td>
<td>${stu.birthday}</td>
<td>${stu.hobby}</td>
<td>${stu.info}</td>
<td><a href="EditServlet?sid=${stu.sid}">更新</a> <a href="#" onclick="doDelete(${stu.sid})">删除</a></td>
</tr>
</c:forEach>
<tr>
<td colspan="8">
第${pageBean.currentPage} / ${pageBean.totalPage}
每页显示${pageBean.pageSize}条
总的记录数${pageBean.totalSize}
<c:if test="${pageBean.currentPage !=1}">
<a href="StudentListPageServlet?currentPage=1">首页</a> |
<a href="StudentListPageServlet?currentPage=${pageBean.currentPage - 1}">上一页</a>
</c:if>
<c:forEach begin="1" end="${pageBean.totalPage}" var="i">
<c:if test="${pageBean.currentPage == i}">
${i}
</c:if>
<c:if test="${pageBean.currentPage != i}">
<a href="StudentListPageServlet?currentPage=${i}">${i}</a>
</c:if>
</c:forEach>
<c:if test="${pageBean.currentPage != pageBean.totalPage}">
<a href="StudentListPageServlet?currentPage=${pageBean.currentPage + 1}">下一页</a> |
<a href="StudentListPageServlet?currentPage=${pageBean.totalPage}">尾页</a>
</c:if>
</td>
</tr>
</table>
</form>
</body>
</html>
7.接收页面请求的Servlet(StudentListPageServlet)
public class StudentListPageServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
// 1.获取需要显示的页码数
int currentPage = Integer.parseInt(request.getParameter("currentPage"));
//2.根据指定的页数,去获取该页的数据回来
StudentServiceImpl service = new StudentServiceImpl();
PageBean pageBean = service.findStudentByPage(currentPage);//封装分页对象数据
request.setAttribute("pageBean",pageBean);
//3.跳转页面
request.getRequestDispatcher("list_page.jsp").forward(request,response);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
逻辑分页(假):
一口气将所有数据全部查询出来,然后放置在内存当中。
优点:访问速度快,只需要访问一次数据库
缺点:数据库量过大,可能内存溢出