对查询出来的记录进行分页显示
1.对查询结果进行分布显示的原因:
如果查询出来的结果一共有上百万条,那么一次性将所有的记录存放在一个list集合中,
这么导致系统内存不足。
2.解决上述问题的方法:
a.对数据库中的记录进行分页查询,MySQL数据库的分布查询语句为:
select * from table_name limit startIndex,length;
注意:对于分页查询,所有的记录的编号是从0开始编号的,length表示
一次查询要显示的结果数。
示例:select * from customer limit 0,10;表示查询前10条记录,即:取查询结果
记录的0-9号记录。
b.从数据库能够分布查询可以看出,要对查询结果达到分页查询,可以根据用户点击的页号来只
查询出这一段的记录即可,而不用一次性将所有的记录都存储起来。这样就可以达到分批的将记录
装载到list集合中,分页显示的目的。
3.具体实现
准备工作:
假设我们有一个Student类,在mysql数据库中我们储存了许多条学生记录:
a.有以下两个实体类
d.web控制层 ShowAllStudentServlet类
1.对查询结果进行分布显示的原因:
如果查询出来的结果一共有上百万条,那么一次性将所有的记录存放在一个list集合中,
这么导致系统内存不足。
2.解决上述问题的方法:
a.对数据库中的记录进行分页查询,MySQL数据库的分布查询语句为:
select * from table_name limit startIndex,length;
注意:对于分页查询,所有的记录的编号是从0开始编号的,length表示
一次查询要显示的结果数。
示例:select * from customer limit 0,10;表示查询前10条记录,即:取查询结果
记录的0-9号记录。
b.从数据库能够分布查询可以看出,要对查询结果达到分页查询,可以根据用户点击的页号来只
查询出这一段的记录即可,而不用一次性将所有的记录都存储起来。这样就可以达到分批的将记录
装载到list集合中,分页显示的目的。
3.具体实现
准备工作:
假设我们有一个Student类,在mysql数据库中我们储存了许多条学生记录:
a.有以下两个实体类
Class Student{
private Sring name;
private int age;
//两个属性的get/set方法
}
设计一个Page对象类: 这个页面类是用于封装一个页面对象
Class Page{
private int totalRecord;//表示查询后一共得到多少条结果记录
private int pageSize; //表示页面一次要显示多少条记录
private int totalPage;//表示将所有的记录进行分页后,一共有多少页
private int startIndex;//表示从所有的结果记录中的哪一个编号开始分页查询
private int pageNum;//表示用户想看的页数
private int List<Student> list;//list集合是用来装载一个页面中的所有记录的
public Page(int pageNum,int totalRecord)
this.pageNum=pageNum;
this.totalRecord=totalRecord;
this.pageSize=10;//设置一页默认显示10条查询记录
this.startInex=(this.pageNum-1)*this.pageSize;//至于为什么this.page要减1,
//是因为mysql数据库对于分页查询时,得到的所有的查询记录,第一条记录的编号是从0开始。
if(this.totalRecord%this.pageSize==0){
this.totalPage=this.totalRecord/this.pageSize;
}else{
this.totalPage=this.totalRecord/this.pageSize+1;
}
}
//每个属性的get/set方法
}
b.在数据访问层DaoImpl类中设计两个方法
/**
*这个方法用于根据查询条件计算出所有符合条件的记录总数
*/
public int getTotalRecord(){
//连接数据库,获取连接,创建语句,此处省略
//select count(*) from student;
//得到的结果集,取出数据
//int totalRecord=.........;
return totalRecord;
}
/**这个方法用于根据用户点击的页面号码来具体查询到这一页中的所有记录
*并将所有的记录封装到Page对象中,交给service层,service层再将结果给上层显示
*/
public Page getPage(int pageNum){
//连接数据库,获取连接,创建语句,此处省略
Page page=new Page(pageNum,this.getTotalRecord());
String sql="select * from student limit ?,?;
PreparedStatemet ps=connection.preparedStatement(sql);
ps.setInt(1,page.getStartIndex());
ps.setInt(2,page.getPageSize());
Result rs=ps.executeQuery();
List<Student>list=new ArrayList<Student>():
while(rs.next()){
Student s=new Student();
s.setName(rs.getString("name"));
s.setAge(rs.getInt("age"));
list.add(s);
}
return page.setList(list);
}
c.在ServiceImpl业务逻辑处理层
Class ServiceImpl{
/**
*这个方法用于先过滤一些无用的数据后,
*再向DaoImpl类的getPage方法获取到Page对象
*/
public Page getPage(String pageNum){
DaoImpl dao=new DaoImpl();
if(pageNum==null){
//用户点击查询所有学生记录时,这时候是没有
//传过来页码的,所有我为默认显示第一页
return dao.getPage(1);
}else{
return dao.getPage(Integer.parseInt(pageNum));
}
}
}
d.web控制层 ShowAllStudentServlet类
Class ShowAllStudentServlet{
public doGet(....){
ServiceImpl service=new ServiceImpl();
String pageNum=request.getParameter("pageNum");//获取到用户点击的页码
Page page=service.getPage(pageNum);
request.setAttribute("page",page);//将page对象存入request域中
request.getRequestDispatcher("/showAllStudent.jsp").forward(request,response);
//将页面转发给数据显示页面
}
}
e.数据显示层 showAllStudent.jsp
<h1>显示所有学生信息</h1>
<table frame="border">
<tr>
<td>姓名</td>
<td>年龄</td>
</tr>
<c:forEach var="stu" items="${requestScope.page.list}">
<tr>
<td>${stu.name}</td>
<td>${stu.age}</td>
</tr>
</c:forEach>
</table>
<!--分查询结果进行分页-->
<c:forEach var="i" begin="1" end="${requestScope.page.totalPage}">
<a href="${pageContext.request.contextPath}/servlet/ShowAllStudentServlet?${i}">${i}</a>
</c:forEach>