前几天做一个系统,用到的是Tomcat+struts+Mysql的MVC框架。由于很多模块都需要分页,想写一个分页的方法。常见的方法每次翻页都查询一次数据库,从ResultSet中只取出一页数据(使用rs.last();rs.getRow()获得总计录条数,使用rs.absolute()定位到本页起始记录)。这种方式在某些数据库(如oracle)的JDBC实现中差不多也是需要遍历所有记录,实验证明在记录数很大时速度非常慢。 至于缓存结果集ResultSet的方法则完全是一种错误的做法。因为ResultSet在Statement或Connection关闭时也会被关闭,如果要使ResultSet有效势必长时间占用数据库连接。 因此比较好的分页做法应该是每次翻页的时候只从数据库里检索页面大小的块区的数据。这样虽然每次翻页都需要查询数据库,但查询出的记录数很少,网络传输数据量不大,如果使用连接池更可以略过最耗时的建立数据库连接过程。而在数据库端有各种成熟的优化技术用于提高查询速度,比在应用服务器层做缓存有效多了。
所以我用到了从数据库中查询当前页面记录的办法。由于设计到公司核心代码的缘故,我就简单的用一个图书的例子介绍一下是我的思路:
开发思路: 我是用Struts的,当然就要使用到MVC这个模式,分页的时候也是这样的。 首先要有一个和数据库链接的bean,我们暂时叫DBUtil吧,这里面封装了很多和数据库有关的东西,比如有查询,修改,插入等方法,这是一个基本的类,这里我们用到的是查询,这个方法返回的数据类型是Object[][]。这里大家要注意一下,你也可以返回别的类型,但是一定要注意把后面对应的程序也修改一下。一下是这个类的部分代码:
package com.model;
import com.attribute.Constants;
import java.sql.*; import java.util.*;
/** * Created by IntelliJ IDEA. * User: 7612CE * Date: 2005-6-2 * Time: 21:41:38 * To change this template use Options | File Templates. */ public class DBUtil {
String sDBDriver=Constants.DBDriver; String url=Constants.DBUrl; String dbUser=Constants.DBUser; String dbPassword=Constants.DBPassword; Connection conn=null; PreparedStatement stmt=null; ResultSet rs=null;
public DBUtil()throws ClassNotFoundException{ try{ Class.forName(sDBDriver); conn=DriverManager.getConnection(url,dbUser,dbPassword); }catch(Exception e){ System.out.println("DBUtil():"+e.getMessage()); } } /** * Search some record in object table * @param sql sql segment * @ param map values for match * @return Collection */ public Object[][] doSearch(String sql,Object [] data)throws SQLException{ PreparedStatement stmt = conn.prepareStatement(sql); for(int i=0;data!=null&&i System.out.print("the aql is ="+sql); System.out.println("data is " + data[i]); stmt.setObject(i+1,data[i]); } ResultSet rset = stmt.executeQuery(); ResultSetMetaData rsm = rset.getMetaData(); int col = rsm.getColumnCount(); ArrayList list = new ArrayList(); //Each element of list contains a record of resultset while(rset.next()){ list.add(getLine(rset,col)); }
if(list.size()==0||col==0){ closePrepStmt(); return null; }
closePrepStmt(); //Construct box as a data matrix Object[][] box = new Object[list.size()][col]; for(int i=0;i for(int j=0;j { box[i][j] =((Object[])list.get(i))[j]; } return box; }
|