对于我们程序员来说,分页是必须掌握的技能。 最近做了几种方式的分页,现在对自己所掌握的分页做一个总结。
以持久层的实现方式来说,分页总是应该存在于DAO中,因为分页也是对于一次数据库查询的操作。分页的方式有许多种,懂大类说分为逻辑分页和物理分页。
逻辑分页的第一种方式: 利用ResultSet的滚动分页。
(1) 根据条件SQL查询数据库
(2) 得到ResultSet的结果集
(3) 利用next()方法,得到分页所需的结果集。
实现代码如下的情景:
/**分页方法, 传入两个参数,分别为“当前页”和“一页显示的数据量”
*/
public List pageList(int currentPage, int pageSize){
... ...
//过滤结果集的变量
int startRecords = (currentPage-1)*pageSize;
int endRecords = (currentPage*pageSize);
int currentNum = 0;
whle(rs.next()){
if(currentNum >=startRecords && courrentNum<endRecords){
pageCustomer.set(....); resultList.add(pageCustomer);
if(currentNum == endRecords-1) break;
}
}
}
这种方法需要取得目标表中的所有数据,并进行分页。
逻辑分页的第二种方式:
逻辑分页的第一种方式使用的是ResultSet, 在支持JDBC2.9的数据库驱动类中, 可以利用ScrollableSets(可滚动的结果集合)来快速定位到某个游标所指定的记录行, 所使用的是ReultSet的absulute()方法, 对ResultSet的滚动分页稍作修改就可以实现ScrollableResults的分页方式。
对上述实例代码的相应位置做出修改就行, 在 //过滤结果集变量 之后
//利用rs.absolut进行定位
if(!rs.absolute(startRecords)){
return resultList;
}
//当返回结果集中有记录时的操作
while(rs.next()){
if(startRecords<endRecords){
set()方法, add()方法
if(startRecords == endRecords-1)
break;
}
startRecords++;
}
第二种方式的效率较第一种方式要好, 但是absolute()方法并不为所有JDBC驱动所支持。
可以利用如下的方式来判断你使用的JDBC驱动是否支持可滚动结果集
//得到ResultSet的类型
int type = rs.getType();
//判断是否支持可滚动结果集
if(type== ResultSet.TYPE_SCROLL_INSENSITIVE || type==ResultSet.TYPE_SCROLL_SENSITIVE){
System.out.println("支持");
}else{
//不支持
}
————————在使用上述的分页方式时遇到了一问题, 先粘贴一个带有错误的版本:
原码如下:(dipage为当前页)
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@10.0.5.69:1521:rat","rat","860110");
System.out.println("conn:"+conn);
stmt=conn.createStatement();
rs=stmt.executeQuery("select * from draft_box");
rs.absolute(1);
int countRecord=0;//记录条数
int countPageRecord=0;//每页记录数
int countPage=0;//总页数
countPageRecord=3;
rs.last();
countRecord=rs.getRow();//得到总页数
System.out.println("countRecord:"+countRecord);
countPage=(countRecord+countPageRecord-1)/countPageRecord;
if((dipage-1)*countPageRecord==0)
rs.beforeFirst();
else
rs.absolute((dipage-1)*countPageRecord+1);
%>
<br>
<div align="center">草稿箱</div>
<br>
<table width="482" border="1" align="center" cellpadding="3" cellspacing="0" bordercolor="#99CCFF">
<tr>
<td width="50"><div align="center">选择</div></td>
<td width="84"><div align="center">标题</div></td>
<td width="76"><div align="center">状态</div></td>
<td width="85"><div align="center">保存日期</div></td>
<td width="84"><div align="center">收件人</div></td>
<td width="111"><div align="center">操作</div></td>
</tr>
<%
int i=0;
while(rs.next()){
%>
<tr>
<td width="50"><div align="center"><input type="checkbox" name="ch"></div></td>
<td width="84"><div align="center"><a href="readmessage.jsp"><%=rs.getString("标题")%></a></div></td>
<td width="50"><div align="center"><%=rs.getString("是否已读")%></div></td>
<td width="110"><div align="center"><%=rs.getDate("日期").toString().substring(0,10)%></div></td>
<td width="84"><div align="center"><%=rs.getString("收件人")%></div></td>
<td width="111"><div align="center"><a href="">删除</a> <a href=">">修改</a></div></td>
</tr>
<%
i++;
if(i>=countPageRecord) break;
}
%>
<tr>
<td colspan=6 align="center">
共<%=countRecord %>条记录,共<%=countPage %>页,当前第<%=dipage %>页,每页<%=countPageRecord %>条记录
<%
if(dipage==1)
;
else{%>
<a href="userpage.jsp?dipage=1">首页</a>
<a href="userpage.jsp?dipage=<%=dipage-1 %>">上一页</a>
<%
}if(dipage==countPage)
;
else{%>
<a href="userpage.jsp?dipage=<%=dipage+1 %>">下一页</a>
<a href="userpage.jsp?dipage=<%=countPage %>">末页</a>
<%
}
conn.close();
}
catch(SQLException e1){
e1.printStackTrace();
}
%>
————————————————————最后提出自己改进的版本————————————————————————
/**
* 封装了订单信息(含分页)————使用的是ResultSet方法
*/
public List selectOrderpageList(PagenationBean pageInfo){
Connection conn = null;
//PreparedStatement pstmt = null;
Statement pstmt = null;
ResultSet rs = null;
String sql = "select * from order_form";
int currentPage = pageInfo.getCurrentPage(); //得到当前页的页号
//System.out.println("我的下一页: "+currentPage);
int pageSize = pageInfo.getPageSize(); //每页显示记录数
conn=DBConnection.getDBConnection();
//过滤结果集的变量
int startRecords = (currentPage-1)*pageSize+1;
int endRecords = (currentPage*pageSize);
int currentNum = (currentPage-1)*pageSize+1;
List resultList = new ArrayList();
try {
pstmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
//pstmt = conn.prepareStatement();
rs = pstmt.executeQuery(sql);
if(startRecords==1){
rs.absolute(startRecords);
rs.beforeFirst();}
else{rs.absolute(startRecords);
rs.previous();
}
//rs.next();
while(rs.next()){
//for(int j=startRecords;j<rs.getFetchSize();j++){System.out.println("总行数为:"+rs.getRow());
System.out.println("circle3:"+currentNum);
if(currentNum>=startRecords && currentNum<=endRecords){
ConsumeOrderBean order_bean = new ConsumeOrderBean();
order_bean.setDdys(rs.getInt("ddys"));
order_bean.setDdzt(rs.getString("ddzt"));
order_bean.setOfid(rs.getInt("ofid"));
order_bean.setOftime(ExValue.getDate(rs.getDate("oftime")));
order_bean.setShr(rs.getString("shr"));
order_bean.setShrdz(rs.getString("shrdz"));
order_bean.setYb(rs.getInt("yb"));
resultList.add(order_bean);
currentNum++;
if(currentNum==endRecords+1)
//currentNum++; System.out.println("跳转之后的页码为: "+currentNum);
//resultList.add(1, currentNum);
break;
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
DBConnection.closeDBResource(conn, pstmt, rs);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return resultList;
}