使用 JdbcRowSet 对象

JdbcRowSet对象是增强的ResultSet对象。就像ResultSet对象一样,它保持与其数据源的连接。最大的区别是它具有一组属性和一个侦听器通知机制,这些机制使它成为 JavaBeans 组件。

JdbcRowSet对象的主要用途之一是使ResultSet对象具有其他功能时可滚动和可更新。

本节涵盖以下主题:

创建 JdbcRowSet 对象

您可以通过多种方式创建JdbcRowSet对象:

  • 通过使用带有ResultSet对象的参考实现构造函数

  • 通过使用带有Connection对象的参考实现构造函数

  • 通过使用参考实现的默认构造函数

  • 通过使用RowSetFactory实例,该实例是从RowSetProvider类创建的

注意 :或者,您可以使用 JDBC 驱动程序的JdbcRowSet实现中的构造函数。但是,RowSetinterface的实现将与参考实现不同。这些实现将具有不同的名称和构造函数。例如,JdbcRowSetinterface的 Oracle JDBC 驱动程序实现称为oracle.jdbc.rowset.OracleJDBCRowSet

传递结果集对象

创建JdbcRowSet对象的最简单方法是生成ResultSet对象,并将其传递给JdbcRowSetImpl构造函数。这样做不仅会创建JdbcRowSet对象,而且还会使用ResultSet对象中的数据填充该对象。

注意 :传递给JdbcRowSetImpl构造函数的ResultSet对象必须是可滚动的。

例如,以下代码片段使用Connection对象con创建Statement对象stmt,然后执行查询。该查询产生ResultSet对象rs,该对象被传递给构造函数以创建一个新的JdbcRowSet对象,该对象用rs中的数据初始化:

stmt = con.createStatement(
           ResultSet.TYPE_SCROLL_SENSITIVE,
           ResultSet.CONCUR_UPDATABLE);
rs = stmt.executeQuery("select * from COFFEES");
jdbcRs = new JdbcRowSetImpl(rs);

ResultSet对象创建的JdbcRowSet对象用作ResultSet对象的包装。由于RowSet对象rs是可滚动和可更新的,因此jdbcRs也可滚动和可更新。如果您运行的方法createStatement不带任何参数,则rs将不会滚动或不可更新,而jdbcRs都不会。

传递连接对象

以下代码摘录自JdbcRowSetSample的第一条语句创建了一个JdbcRowSet对象,该对象通过Connection对象con连接到数据库:

jdbcRs = new JdbcRowSetImpl(con);
jdbcRs.setCommand("select * from COFFEES");
jdbcRs.execute();

在您使用方法setCommand指定一条 SQL 语句,然后运行方法execute之前,对象jdbcRs不包含任何数据。

对象jdbcRs是可滚动和可更新的;默认情况下,除非另有说明,否则JdbcRowSet和所有其他RowSet对象是可滚动和可更新的。有关您可以指定的JdbcRowSet属性的更多信息,请参见默认的 JdbcRowSet 对象

使用默认构造函数

下面的代码摘录中的第一条语句创建一个空的JdbcRowSet对象。

public void createJdbcRowSet(String username, String password) {

    jdbcRs = new JdbcRowSetImpl();
    jdbcRs.setCommand("select * from COFFEES");
    jdbcRs.setUrl("jdbc:myDriver:myAttribute");
    jdbcRs.setUsername(username);
    jdbcRs.setPassword(password);
    jdbcRs.execute();
    // ...
}

在使用方法setCommand指定一条 SQL 语句,指定JdbcResultSet对象如何连接数据库,然后运行方法execute之前,对象jdbcRs不包含任何数据。

所有参考实现构造函数都为默认的 JdbcRowSet 对象部分中列出的属性分配默认值。

使用 RowSetFactory interface

使用 Java SE 7 和更高版本中的 RowSet 1.1,您可以使用RowSetFactory的实例创建JdbcRowSet对象。例如,以下代码摘录使用RowSetFactoryinterface的实例创建JdbcRowSet对象jdbcRs

public void createJdbcRowSetWithRowSetFactory(
    String username, String password)
    throws SQLException {

    RowSetFactory myRowSetFactory = null;
    JdbcRowSet jdbcRs = null;
    ResultSet rs = null;
    Statement stmt = null;

    try {
        myRowSetFactory = RowSetProvider.newFactory();
        jdbcRs = myRowSetFactory.createJdbcRowSet();

        jdbcRs.setUrl("jdbc:myDriver:myAttribute");
        jdbcRs.setUsername(username);
        jdbcRs.setPassword(password);

        jdbcRs.setCommand("select * from COFFEES");
        jdbcRs.execute();

        // ...
    }
}

以下语句使用默认的RowSetFactory实现com.sun.rowset.RowSetFactoryImpl创建RowSetProvider对象myRowSetFactory

myRowSetFactory = RowSetProvider.newFactory();

或者,如果您的 JDBC 驱动程序具有自己的RowSetFactory实现,则可以将其指定为newFactory方法的参数。

以下语句创建JdbcRowSet对象jdbcRs并配置其数据库连接属性:

jdbcRs = myRowSetFactory.createJdbcRowSet();
jdbcRs.setUrl("jdbc:myDriver:myAttribute");
jdbcRs.setUsername(username);
jdbcRs.setPassword(password);

RowSetFactoryinterface包含用于创建 RowSet 1.1 和更高版本中可用的不同类型的RowSet实现的方法:

  • createCachedRowSet

  • createFilteredRowSet

  • createJdbcRowSet

  • createJoinRowSet

  • createWebRowSet

默认的 JdbcRowSet 对象

使用默认构造函数创建JdbcRowSet对象时,新的JdbcRowSet对象将具有以下属性:

  • typeResultSet.TYPE_SCROLL_INSENSITIVE(具有可滚动的光标)

  • concurrencyResultSet.CONCUR_UPDATABLE(可以更新)

  • escapeProcessingtrue(驱动程序将进行转义处理;启用转义处理后,驱动程序将扫描任何转义语法并将其转换为特定数据库可以理解的代码)

  • maxRows0(行数没有限制)

  • maxFieldSize0(列值的字节数没有限制;仅适用于存储BINARYVARBINARYLONGVARBINARYCHARVARCHARLONGVARCHAR值的列)

  • queryTimeout0(执行查询所需的时间没有时间限制)

  • showDeletedfalse(删除的行不可见)

  • transactionIsolationConnection.TRANSACTION_READ_COMMITTED(仅读取已提交的数据)

  • typeMapnull(与此RowSet对象使用的Connection对象关联的类型 Map 为null)

您必须从该列表记住的主要事情是,除非您为这些属性设置了不同的值,否则JdbcRowSet和所有其他RowSet对象是可滚动和可更新的。

Setting Properties

默认的 JdbcRowSet 对象部分列出了在创建新的JdbcRowSet对象时默认设置的属性。如果使用默认构造函数,则必须设置一些其他属性,然后才能用数据填充新的JdbcRowSet对象。

为了获取其数据,一个JdbcRowSet对象首先需要连接到数据库。以下四个属性保存用于获得与数据库的连接的信息。

  • username:用户为获得访问权限而提供给数据库的名称

  • password:用户的数据库密码

  • url:用户要连接到的数据库的 JDBC URL

  • datasourceName:用于检索已向 JNDI 命名服务注册的DataSource对象的名称

您设置的这些属性中的哪一个取决于您将如何构建连接。首选方法是使用DataSource对象,但是使用 JNDI 命名服务注册DataSource对象可能不切实际,这通常是由系统 管理 员完成的。因此,所有代码示例均使用DriverManager机制来获取连接,为此您使用url属性而不是datasourceName属性。

您必须设置的另一个属性是command属性。此属性是确定JdbcRowSet对象将保存哪些数据的查询。例如,以下代码行通过查询设置command属性,该查询生成一个ResultSet对象,该对象包含表COFFEES中的所有数据:

jdbcRs.setCommand("select * from COFFEES");

设置command属性和进行连接所必需的属性后,可以通过调用execute方法为jdbcRs对象填充数据。

jdbcRs.execute();

execute方法在后台为您做很多事情:

  • 它使用您分配给urlusernamepassword属性的值构建与数据库的连接。

  • 它执行您在command属性中设置的查询。

  • 它将数据从产生的ResultSet对象读取到jdbcRs对象。

使用 JdbcRowSet 对象

您更新,插入和删除JdbcRowSet对象中的行的方式与更新,插入和删除可更新ResultSet对象中的行的方式相同。同样,以与浏览可滚动ResultSet对象相同的方式浏览JdbcRowSet对象。

咖啡馆的 Coffee Break 链收购了另一家咖啡馆,并且现在具有不支持滚动或更新结果集的旧数据库。换句话说,此旧数据库生成的任何ResultSet对象都没有可滚动的游标,并且其中的数据也无法修改。但是,通过创建一个JdbcRowSet对象,其中填充了ResultSet对象中的数据,实际上,您可以使ResultSet对象可滚动和可更新。

如前所述,默认情况下JdbcRowSet对象是可滚动和可更新的。因为其内容与ResultSet对象中的内容相同,所以对JdbcRowSet对象进行操作等同于对ResultSet对象本身进行操作。而且,由于JdbcRowSet对象与数据库之间存在持续的连接,因此它对自己的数据所做的更改也会对数据库中的数据进行更改。

本节涵盖以下主题:

导航 JdbcRowSet 对象

不可滚动的ResultSet对象只能使用next方法将光标向前移动,并且只能将光标从第一行移动到最后一行。但是,默认的JdbcRowSet对象可以使用ResultSetinterface中定义的所有光标移动方法。

JdbcRowSet对象可以调用方法next,也可以调用其他ResultSet光标移动方法中的任何一个。例如,以下代码行将光标移动到jdbcRs对象的第四行,然后移回第三行:

jdbcRs.absolute(4);
jdbcRs.previous();

方法previous与方法next类似,因为它可以在while循环中用于按 Sequences 遍历所有行。区别在于您必须将光标移到最后一行之后的位置,而previous则将光标移到开头。

更新列值

您可以像更新ResultSet对象中的数据一样来更新JdbcRowSet对象中的数据。

假设 Coffee Break 的所有者想提高一磅 Espresso 咖啡的价格。如果所有者知道 Espresso 在jdbcRs对象的第三行中,则执行此操作的代码应如下所示:

jdbcRs.absolute(3);
jdbcRs.updateFloat("PRICE", 10.99f);
jdbcRs.updateRow();

该代码将光标移动到第三行,并将PRICE列的值更改为 10.99,然后使用新价格更新数据库。

调用方法updateRow将更新数据库,因为jdbcRs保持了与数据库的连接。对于断开连接的RowSet对象,情况有所不同。

Inserting Rows

如果 Coffee Break 链的所有者想要在他提供的产品中添加一种或多种咖啡,则所有者需要为每种新咖啡在COFFEES表中添加一行,如JdbcRowSetSample的以下代码片段所述。请注意,由于jdbcRs对象始终连接到数据库,因此在JdbcRowSet对象中插入行与在ResultSet对象中插入行是相同的:将光标移至插入行,请使用适当的 updater 方法来设置每个列的值,并调用方法insertRow

jdbcRs.moveToInsertRow();
jdbcRs.updateString("COF_NAME", "HouseBlend");
jdbcRs.updateInt("SUP_ID", 49);
jdbcRs.updateFloat("PRICE", 7.99f);
jdbcRs.updateInt("SALES", 0);
jdbcRs.updateInt("TOTAL", 0);
jdbcRs.insertRow();

jdbcRs.moveToInsertRow();
jdbcRs.updateString("COF_NAME", "HouseDecaf");
jdbcRs.updateInt("SUP_ID", 49);
jdbcRs.updateFloat("PRICE", 8.99f);
jdbcRs.updateInt("SALES", 0);
jdbcRs.updateInt("TOTAL", 0);
jdbcRs.insertRow();

当您调用方法insertRow时,新行将插入到jdbcRs对象中,并且还将插入到数据库中。前面的代码片段经过两次此过程,因此在jdbcRs对象和数据库中插入了两个新行。

Deleting Rows

就像更新数据并插入新行一样,对于JdbcRowSet对象和ResultSet对象,删除行是相同的。所有者希望停止销售jdbcRs对象的最后一行的法式烘焙脱 Caffeine 咖啡。在以下代码行中,第一行将光标移动到最后一行,第二行从jdbcRs对象和数据库中删除最后一行:

jdbcRs.last();
jdbcRs.deleteRow();

Code Sample

samplesJdbcRowSetSample执行以下操作:

  • 创建一个新的JdbcRowSet对象,该对象以ResultSet对象初始化,该对象是通过执行查询生成的,该查询检索COFFEES表中的所有行

  • 将光标移动到COFFEES表的第三行并更新该行中的PRICE

  • 插入两行,一行用于HouseBlend,另一行用于HouseDecaf

  • 将光标移到最后一行并将其删除