Java教程是针对JDK 8编写的。本页面中描述的示例和实践不利用后续版本引入的改进,并且可能使用不再可用的技术。
有关Java SE 9及后续版本中更新的语言功能的摘要,请参阅Java语言更改。
有关所有JDK版本的新功能、增强功能和已删除或已弃用选项的信息,请参阅JDK发行说明。
JdbcRowSet对象是一个增强版的ResultSet对象。它与数据源保持连接,就像ResultSet对象一样。区别在于,它具有一组属性和一个监听器通知机制,使它成为JavaBeans组件。
JdbcRowSet对象的主要用途之一是使没有滚动和更新能力的ResultSet对象具备这些功能。
本节涵盖以下主题:
使用RowSetFactory的实例来创建JdbcRowSet对象,该实例由RowSetProvider类创建。以下示例来自JdbcRowSetSample.java:
RowSetFactory factory = RowSetProvider.newFactory();
try (JdbcRowSet jdbcRs = factory.createJdbcRowSet()) {
jdbcRs.setUrl(this.settings.urlString);
jdbcRs.setUsername(this.settings.userName);
jdbcRs.setPassword(this.settings.password);
jdbcRs.setCommand("select * from COFFEES");
jdbcRs.execute();
// ...
RowSetFactory接口包含创建不同类型RowSet实现的方法:
createCachedRowSetcreateFilteredRowSetcreateJdbcRowSetcreateJoinRowSetcreateWebRowSet当使用RowSetFactory的实例创建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对象关联的类型映射为null)从这个列表中你必须记住的主要事项是,JdbcRowSet和所有其他RowSet对象都是可滚动和可更新的,除非你为这些属性设置了不同的值。
当创建一个新的JdbcRowSet对象时,默认情况下设置了默认JdbcRowSet对象中列出的属性。如果你使用默认构造函数,你必须在将新的JdbcRowSet对象填充数据之前设置一些额外的属性。
为了获取它的数据,一个JdbcRowSet对象首先需要连接到一个数据库。以下四个属性保存了获取数据库连接时使用的信息。
username:用户在获得访问权限时向数据库提供的用户名password:用户的数据库密码url:用户想要连接的数据库的JDBC URLdatasourceName:用于检索已在JNDI命名服务中注册的DataSource对象的名称你设置的这些属性取决于你如何进行连接。首选的方式是使用DataSource对象,但是你可能无法将DataSource对象注册到JNDI命名服务中,这通常由系统管理员完成。因此,代码示例都使用DriverManager机制来获取连接,你使用的是url属性而不是datasourceName属性。
你还必须设置的另一个属性是command属性。这个属性是确定JdbcRowSet对象将包含哪些数据的查询。例如,以下代码行使用查询设置了command属性,该查询产生一个包含表COFFEES中所有数据的ResultSet对象:
jdbcRs.setCommand("select * from COFFEES");
在设置了command属性和用于建立连接的属性之后,你可以通过调用execute方法来填充jdbcRs对象的数据。
jdbcRs.execute();
execute方法在后台为你执行了许多操作:
url、username和password属性分配的值连接到数据库。command属性中设置的查询。ResultSet对象中的数据读取到jdbcRs对象中。你可以通过相同的方式在JdbcRowSet对象中更新、插入和删除行,就像在可更新的ResultSet对象中一样。同样,你可以通过相同的方式在JdbcRowSet对象中导航,就像在可滚动的ResultSet对象中一样。
Coffee Break咖啡连锁店收购了另一家连锁咖啡店,现在有一个不支持滚动或更新结果集的传统数据库。换句话说,由该传统数据库生成的任何ResultSet对象都没有可滚动的游标,其中的数据也无法修改。然而,通过创建一个从ResultSet对象中获取数据的JdbcRowSet对象,你可以实际上使ResultSet对象可滚动和可更新。
如前所述,JdbcRowSet对象默认情况下是可滚动和可更新的。因为它的内容与ResultSet对象中的内容相同,所以对JdbcRowSet对象的操作等同于对ResultSet对象本身的操作。并且由于JdbcRowSet对象与数据库有持续的连接,它对自身数据的更改也会应用到数据库中的数据。
本节涵盖以下主题:
一个不可滚动的ResultSet对象只能使用next方法将其游标向前移动,并且只能从第一行向最后一行移动游标。然而,默认的JdbcRowSet对象可以使用ResultSet接口中定义的所有游标移动方法。
JdbcRowSet对象可以调用next方法,也可以调用任何其他ResultSet游标移动方法。例如,以下代码将游标移动到jdbcRs对象的第四行,然后回到第三行:
jdbcRs.absolute(4); jdbcRs.previous();
previous方法类似于next方法,可以在while循环中用于按顺序遍历所有行。不同之处在于你必须将游标移动到最后一行之后的位置,而previous方法将游标向前移动。
你可以通过与ResultSet对象相同的方式更新JdbcRowSet对象中的数据。
假设咖啡休息的老板想要提高一磅浓缩咖啡的价格。如果老板知道浓缩咖啡在jdbcRs对象的第三行,可以使用以下代码来完成:
jdbcRs.absolute(3);
jdbcRs.updateFloat("PRICE", 10.99f);
jdbcRs.updateRow();
这段代码将光标移动到第三行,并将PRICE列的值更改为10.99,然后使用新的价格更新数据库。
调用方法updateRow会更新数据库,因为jdbcRs保持与数据库的连接。对于断开连接的RowSet对象,情况是不同的。
如果咖啡休息连锁店的老板想要增加所提供的咖啡数量,他将需要为每一种新咖啡在COFFEES表中添加一行,就像在JdbcRowSetSample.java的以下代码片段中所做的一样。请注意,由于jdbcRs对象始终连接到数据库,因此向JdbcRowSet对象中插入一行与向ResultSet对象中插入一行是相同的:将光标移动到插入行,使用适当的更新器方法为每个列设置一个值,然后调用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对象和数据库中插入了两行新数据。
与更新数据和插入新行一样,删除行对于JdbcRowSet对象和ResultSet对象是相同的。老板想要停止销售法式烘焙无咖啡因咖啡,它是jdbcRs对象中的最后一行。在以下代码中,第一行将光标移动到最后一行,第二行从jdbcRs对象和数据库中删除最后一行:
jdbcRs.last(); jdbcRs.deleteRow();
示例JdbcRowSetSample.java执行以下操作:
JdbcRowSet对象,并用执行检索COFFEES表中所有行的查询所产生的ResultSet对象进行初始化COFFEES表的第三行,并更新该行中的PRICE列HouseBlend,一个为HouseDecaf