使用 JdbcRowSet 对象
JdbcRowSet
对象是增强的ResultSet
对象。就像ResultSet
对象一样,它保持与其数据源的连接。最大的区别是它具有一组属性和一个侦听器通知机制,这些机制使它成为 JavaBeans 组件。
JdbcRowSet
对象的主要用途之一是使ResultSet
对象具有其他功能时可滚动和可更新。
本节涵盖以下主题:
创建 JdbcRowSet 对象
您可以通过多种方式创建JdbcRowSet
对象:
-
通过使用带有
ResultSet
对象的参考实现构造函数 -
通过使用带有
Connection
对象的参考实现构造函数 -
通过使用参考实现的默认构造函数
-
通过使用
RowSetFactory
实例,该实例是从RowSetProvider
类创建的
注意 :或者,您可以使用 JDBC 驱动程序的JdbcRowSet
实现中的构造函数。但是,RowSet
interface的实现将与参考实现不同。这些实现将具有不同的名称和构造函数。例如,JdbcRowSet
interface的 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
对象。例如,以下代码摘录使用RowSetFactory
interface的实例创建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);
RowSetFactory
interface包含用于创建 RowSet 1.1 和更高版本中可用的不同类型的RowSet
实现的方法:
-
createCachedRowSet
-
createFilteredRowSet
-
createJdbcRowSet
-
createJoinRowSet
-
createWebRowSet
默认的 JdbcRowSet 对象
使用默认构造函数创建JdbcRowSet
对象时,新的JdbcRowSet
对象将具有以下属性:
-
type
:ResultSet.TYPE_SCROLL_INSENSITIVE
(具有可滚动的光标) -
concurrency
:ResultSet.CONCUR_UPDATABLE
(可以更新) -
escapeProcessing
:true
(驱动程序将进行转义处理;启用转义处理后,驱动程序将扫描任何转义语法并将其转换为特定数据库可以理解的代码) -
maxRows
:0
(行数没有限制) -
maxFieldSize
:0
(列值的字节数没有限制;仅适用于存储BINARY
,VARBINARY
,LONGVARBINARY
,CHAR
,VARCHAR
和LONGVARCHAR
值的列) -
queryTimeout
:0
(执行查询所需的时间没有时间限制) -
showDeleted
:false
(删除的行不可见) -
transactionIsolation
:Connection.TRANSACTION_READ_COMMITTED
(仅读取已提交的数据) -
typeMap
:null
(与此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
方法在后台为您做很多事情:
-
它使用您分配给
url
,username
和password
属性的值构建与数据库的连接。 -
它执行您在
command
属性中设置的查询。 -
它将数据从产生的
ResultSet
对象读取到jdbcRs
对象。
使用 JdbcRowSet 对象
您更新,插入和删除JdbcRowSet
对象中的行的方式与更新,插入和删除可更新ResultSet
对象中的行的方式相同。同样,以与浏览可滚动ResultSet
对象相同的方式浏览JdbcRowSet
对象。
咖啡馆的 Coffee Break 链收购了另一家咖啡馆,并且现在具有不支持滚动或更新结果集的旧数据库。换句话说,此旧数据库生成的任何ResultSet
对象都没有可滚动的游标,并且其中的数据也无法修改。但是,通过创建一个JdbcRowSet
对象,其中填充了ResultSet
对象中的数据,实际上,您可以使ResultSet
对象可滚动和可更新。
如前所述,默认情况下JdbcRowSet
对象是可滚动和可更新的。因为其内容与ResultSet
对象中的内容相同,所以对JdbcRowSet
对象进行操作等同于对ResultSet
对象本身进行操作。而且,由于JdbcRowSet
对象与数据库之间存在持续的连接,因此它对自己的数据所做的更改也会对数据库中的数据进行更改。
本节涵盖以下主题:
导航 JdbcRowSet 对象
不可滚动的ResultSet
对象只能使用next
方法将光标向前移动,并且只能将光标从第一行移动到最后一行。但是,默认的JdbcRowSet
对象可以使用ResultSet
interface中定义的所有光标移动方法。
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
-
将光标移到最后一行并将其删除