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
实现的方法:
createCachedRowSet
createFilteredRowSet
createJdbcRowSet
createJoinRowSet
createWebRowSet
当使用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