`
wazhyu
  • 浏览: 19271 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

JDBC分页-据说不错拿来学学

阅读更多
注:转载于某个网站(不记得了)。
 
前言

  在使用数据库的过程中,不可避免的需要使用到分页的功能,可是JDBC的规范对此却没有很好的解决。对于这个需求很多朋友都有自己的解决方案,比如使用Vector等集合类先保存取出的数据再分页。但这种方法的可用性很差,与JDBC本身的接口完全不同,对不同类型的字段的支持也不好。这里提供了一种与JDBC兼容性非常好的方案。 

  JDBC和分页

  Sun的JDBC规范的制定,有时很让人哭笑不得,在JDBC1.0中,对于一个结果集(ResultSet)你甚至只能执行next()操作,而无法让其向后滚动,这就直接导致在只执行一次SQL查询的情况下无法获得结果集的大小。所以,如果你使用的是JDBC1.0的驱动,那么是几乎无法实现分页的。

  好在Sun的JDBC2规范中很好的弥补了这一个不足,增加了结果集的前后滚动操作,虽然仍然不能直接支持分页,但我们已经可以在这个基础上写出自己的可支持分页的ResultSet了。


  一个新的Pageable接口及其实现

  很显然,看过上面三种实现方法后,我们对新的分页机制有了一个目标,即:不与具体数据库相关;尽可能做到代码重用;尽可能与原JDBC接口的使用方法保持一致;尽可能高的效率。

  首先,我们需要提供一个与java.sql.ResultSet向下兼容的接口,把它命名为Pageable,接口定义如下:

public interface Pageable extends java.sql.ResultSet{
/**返回总页数
*/
int getPageCount();
/**返回当前页的记录条数
*/
int getPageRowsCount();
/**返回分页大小
*/
int getPageSize();
/**转到指定页
*/
void gotoPage(int page) ;
/**设置分页大小
*/
void setPageSize(int pageSize);
/**返回总记录行数
*/
int getRowsCount();
/**
* 转到当前页的第一条记录
* @exception java.sql.SQLException 异常说明。
*/
void pageFirst() throws java.sql.SQLException;
/**
* 转到当前页的最后一条记录
* @exception java.sql.SQLException 异常说明。
*/
void pageLast() throws java.sql.SQLException;
/**返回当前页号
*/
int getCurPage();

  这是一个对java.sql.ResultSet进行了扩展的接口,主要是增加了对分页的支持,如设置分页大小,跳转到某一页,返回总页数等等。

  接着,我们需要实现这个接口,由于这个接口继承自ResultSet,并且它的大部分功能也都和ResultSet原有功能相同,所以这里使用了一个简单的Decorator模式。

  PageableResultSet2的类声明和成员声明如下:

public class PageableResultSet2 implements Pageable {
    protected java.sql.ResultSet rs=null;
    protected int rowsCount;
    protected int pageSize;
    protected int curPage;
    protected String command = "";

  可以看到,在PageableResultSet2中,包含了一个ResultSet的实例(这个实例只是实现了ResultSet接口,事实上它是由各个数据库厂商分别实现的),并且把所有由ResultSet继承来的方法都直接转发给该实例来处理。

  PageableResultSet2中继承自ResultSet的主要方法:

//……
public boolean next() throws SQLException {
    return rs.next();
}
//……
public String getString(String columnName) throws SQLException {
    try {
        return rs.getString(columnName);
    }
    catch (SQLException e) {//这里是为了增加一些出错信息的内容便于调试
        throw new SQLException (e.toString()+" columnName="
            +columnName+" SQL="+this.getCommand());
    }
}
//…… 
  只有在Pageable接口中新增的方法才需要自己的写方法处理。
/**方法注释可参考Pageable.java
*/
public int getCurPage() {
    return curPage;
}
public int getPageCount() {
    if(rowsCount==0) return 0;
    if(pageSize==0) return 1;
    //calculate PageCount
    double tmpD=(double)rowsCount/pageSize;
    int tmpI=(int)tmpD;
    if(tmpD>tmpI) tmpI++;
    return tmpI;
}
public int getPageRowsCount() {
    if(pageSize==0) return rowsCount;
    if(getRowsCount()==0) return 0;
    if(curPage!=getPageCount()) return pageSize;
    return rowsCount-(getPageCount()-1)*pageSize;
}
public int getPageSize() {
    return pageSize;
}
public int getRowsCount() {
    return rowsCount;
}
public void gotoPage(int page) {
    if (rs == null)
        return;
    if (page < 1)
        page = 1;
    if (page > getPageCount())
        page = getPageCount();
    int row = (page - 1) * pageSize + 1;
    try {
        rs.absolute(row);
        curPage = page;
    }
    catch (java.sql.SQLException e) {
    }
}
public void pageFirst() throws java.sql.SQLException {
    int row=(curPage-1)*pageSize+1;
    rs.absolute(row);
}
public void pageLast() throws java.sql.SQLException {
    int row=(curPage-1)*pageSize+getPageRowsCount();
    rs.absolute(row);
}
public void setPageSize(int pageSize) {
    if(pageSize>=0){
        this.pageSize=pageSize;
        curPage=1;
    }

  //PageableResultSet2的构造方法:
public PageableResultSet2(java.sql.ResultSet rs) throws java.sql.SQLException {
    if(rs==null) throw new SQLException("given ResultSet is NULL","user");
    rs.last();
    rowsCount=rs.getRow();
    rs.beforeFirst();
    this.rs=rs;


/*如果要提高效率,可以利用select count(*) 语句取得所有记录数,注释掉构造函数的rs.last();rowsCount=rs.getRow();rs.beforeFirst();三句。在调用构造函数后调用此方法获得所有的记录,参数是select count(*)后的结果集
*/
public void setRowsCount(java.sql.ResultSet rs)throws java.sql.SQLException {
   if(rs==null) throw new SQLException("given ResultSet is NULL","user");
   rowCount=rs.getInt(1);
}

  这里只是简单的取得一个总记录数,并将记录游标移回初始位置(before first),同时将参数中的ResultSet赋给成员变量。

  这里只是简单的取得一个总记录数,并将记录游标移回初始位置(before first),同时将参数中的ResultSet赋给成员变量。

  Pageable的使用方法

  因为Pageable接口继承自ResultSet,所以在使用方法上与ResultSet一致,尤其是在不需要分页功能的时候,可以直接当成ResultSet使用。而在需要分页时,只需要简单的setPageSize, gotoPage,即可。

PreparedStatement pstmt=null;
Pageable rs=null;
……//构造SQL,并准备一个pstmt.
rs=new PageableResultSet2(pstmt.executeQuery());//构造一个Pageable
rs.setPageSize(20);//每页20个记录
rs.gotoPage(2);//跳转到第2页
for(int i=0; i<rs.getPageRowsCount(); i++){//循环处理
int id=rs.getInt(“ID”);
……//继续处理
rs.next();
}
  总结

  一个好的基础类应该是便于使用,并且具备足够的可移植性,同时要保证其功能的完善。在上面的实现中,我们从java.sql.ResultSet接口继承出Pageable,并实现了它。这就保证了在使用中与JDBC原有操作的一致性,同时对原有功能没有缩减。

  同时它也是易于使用的,因为封装了一切必要的操作,所以在你的代码中唯一显得"难看"和"不舒服"的地方就是需要自己去构造一个PageableResultSet2。不过只要你愿意,这也是可以解决的。

  当然它也有具有充分的可移植性,当你将数据库由Oracle变为Mysql或者SQLServer的时候,你仍然可以使用这些分页的代码。它在使用中(或者说在移植的过程中)唯一的限制就是你必须要使用一个支持JDBC2的驱动(现在明白为什么我把类命名为PageableResultSet2了吧。:P),不过,好在JDBC2已经成为标准了,绝大多数的数据库(如Oracle, Mysql, SQLServer)都有自己的或者第三方提供的JDBC2的驱动。

  OK,这个分页的实现是否对你的编程有帮助呢?仔细看看,其实真正自己写的代码并不多的,大部分都只是简单的转发操作。一个合适的模式应用可以帮你很大忙。
分享到:
评论

相关推荐

    jdbc--sqljdbc4-2.0.jar

    java链接sqlserver数据库包如下错误时: java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver at java.net.URLClassLoader.findClass(Unknown Source) ...添加sqljdbc4-2.0包即可

    sqljdbc4-4.0.jar.rar

    《SQL Server 数据库连接驱动:sqljdbc4-4.0.jar 深度解析》 在信息化社会中,数据库管理系统的角色至关重要,SQL Server作为微软公司推出的强大关系型数据库管理系统,广泛应用于各种业务场景。而要与SQL Server...

    sqljdbc4-3.0.jar

    在描述中提到,“JAVA支持SQL SERVICE 2000版本的JDBC”,这指的是该驱动是Java语言开发的,它实现了Java Database Connectivity (JDBC) API,使得Java开发者能够通过标准的JDBC接口来访问和管理SQL Server 2000...

    dm8-oracle-jdbc16-wrapper.jar

    dm8-oracle-jdbc16-wrapper.jar

    maven 下载 sqljdbc4-4.0.jar

    在Java编程环境中,连接Microsoft SQL Server数据库通常需要特定的驱动程序,这就是所谓的JDBC驱动程序。`sqljdbc4-4.0.jar`是Microsoft提供的一个适用于Java的SQL Server JDBC驱动程序,它允许Java应用程序通过JDBC...

    sqljdbc4-chs-4.0.2206.100.jar

    sqljdbc4-chs-4.0.2206.100.jar sqljdbc4-chs-4.0.2206.100.jar sqljdbc4-chs-4.0.2206.100.jar sqljdbc4 com.microsoft.sqlserver sqlserver

    sqljdbc4-4.0.jar

    首先,我们来理解一下"sqljdbc4-4.0.jar"的含义。"sqljdbc"代表这是针对SQL Server的JDBC驱动,而"4.0"则表示该驱动的版本号,它符合JDBC 4.0规范,提供了对Java SE 6的支持。这个版本的驱动引入了多项新特性和性能...

    含两个文件hive-jdbc-3.1.2-standalone.jar和apache-hive-3.1.2-bin.tar.gz

    含两个文件hive-jdbc-3.1.2-standalone.jar和apache-hive-3.1.2-bin.tar.gz 含两个文件hive-jdbc-3.1.2-standalone.jar和apache-hive-3.1.2-bin.tar.gz 含两个文件hive-jdbc-3.1.2-standalone.jar和apache-hive-...

    x-pack-sql-jdbc-6.4-7.6各个版本jdbc驱动--百度网盘下载

    x-pack-sql-jdbc-6.4.0到x-pack-sql-jdbc-7.6.0各个版本jdbc驱动下载

    sqljdbc4-4.0.jar下载 《无需积分》,自行提取

    sqljdbc4-4.0.jar下载 《无需积分》,自行提取 Maven安装cmd指令 mvn install:install-file -DgroupId=com.microsoft.sqlserver -DartifactId=sqljdbc4 -Dversion=4.0 -Dpackaging=jar -Dfile=G:\迅雷下载\BB-sql...

    sqljdbc4-4.0.jar包.zip

    通过JDBC,Java程序员可以编写代码来执行SQL语句,处理查询结果,以及管理数据库连接。JDBC驱动程序是连接Java应用程序与数据库的关键组件,它们实现了JDBC API,提供了具体的数据库访问功能。 **二、sqljdbc4-4.0....

    clickhouse-jdbc-0.2.4.jar 和 clickhouse-jdbc-0.2.4-jar-with-dependencies.jar

    这两个文件`clickhouse-jdbc-0.2.4.jar`和`clickhouse-jdbc-0.2.4-jar-with-dependencies.jar`都是Clickhouse-JDBC驱动的不同版本。 `clickhouse-jdbc-0.2.4.jar`是基础的JAR文件,它包含了Clickhouse-JDBC驱动的...

    taos-jdbcdriver-2.0.39-dist.jar

    taos-jdbcdriver-2.0.39-dist.jar

    Java 第三阶段增强分析需求,代码实现能力【JDBC】---- 代码

    Java 第三阶段增强分析需求,代码实现能力【JDBC】---- 代码 Java 第三阶段增强分析需求,代码实现能力【JDBC】---- 代码 Java 第三阶段增强分析需求,代码实现能力【JDBC】---- 代码 Java 第三阶段增强分析需求,...

    hive-jdbc-3.1.2-standalone

    hive-jdbc-3.1.2-standalone适用于linux

    连接MS SQLSERVER 的驱动jar包sqljdbc4-3.0.zip

    本文将详细讲解如何使用“sqljdbc4-3.0.zip”这个驱动包来实现MS SQL Server的连接。 `sqljdbc4-3.0.jar`是Microsoft为Java开发人员提供的一个JDBC驱动程序,它允许Java应用程序通过JDBC API与SQL Server进行通信。...

    hive-jdbc-2.1.0-standalone.jar

    hive-jdbc-2.1.0-standalone.jar

    sqlite-jdbc-3.15.1-API文档-中文版.zip

    赠送jar包:sqlite-jdbc-3.15.1.jar; 赠送原API文档:sqlite-jdbc-3.15.1-javadoc.jar; 赠送源代码:sqlite-jdbc-3.15.1-sources.jar; 赠送Maven依赖信息文件:sqlite-jdbc-3.15.1.pom; 包含翻译后的API文档:...

    taos-jdbcdriver-2.0.34-dist.jar

    TDengine驱动Jar包(2.0.34)

    sqljdbc4-4.0.zip

    完成上述配置后,Java程序便可以使用`java.sql.DriverManager`类来建立与SQL Server的连接,例如: ```java Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); Connection conn = DriverManager.get...

Global site tag (gtag.js) - Google Analytics