13.5 管理结果集
JDBC
使用ResultSet
来封装执行查询得到的查询结果,然后通过移动ResultSet
的记录指针来取出结果集的内容。除此之外,JDBC
还允许通过ResultSet
来更新记录,并提供了ResultSetMetaData
来获得ResultSet
对象的相关信息。
13.5.1 可滚动,可更新的结果集
前面提到, ResultSet
定位记录指针的方法有absolute()
、 previous()
等方法,但前面程序自始至终都只用了next()
方法来移动记录指针,实际上也可以使用absolute()
、 previous()
、 last()
等方法来移动记录指针。
可以使用absolute()
、 previous()
、 afterLast()
等方法自由移动记录指针的ResultSet()
被称为可滚动的结果集。
Java 5以后 ResultSet 默认可滚动
在JDK1.4
以前,默认打开的ResultSet
是不可滚动的,必须在创建Statement
或PreparedStatement
时传入额外的参数。从Java 5.0
以后,默认打开的ResultSet
就是可滚动的,无须传入额外的参数.
以默认方式打开的ResultSet
是不可更新的,如果希望创建可更新的ResultSet
,则必须在创建Statement
或PreparedStatement
时传入额外的参数。
Connection
在创建Statement
或PreparedStatement
时还可额外传入如下两个参数。
resultSetType
:控制ResultSet
的类型,该参数可以取如下三个值。ResultSet.TYPE_FOWARD_ONLY
:该常量控制记录指针只能向前移动。这是JDK 1.4
以前的默认值。ResultSet.TYPE_SCROLL_INSENSITIVE
:该常量控制记录指针可以自由移动(可滚动结果集),但底层数据的改变不会影响ResultSet
的内容。ResultSet.TYPE_SCROLL_SENSITIVE
:该常量控制记录指针可以自由移动(可滚动结果集),而且底层数据的改变会影响ResultSet
的内容。
resultSetConcurrency
:控制ResultSet
的并发类型
,该参数可以接收如下两个值。ResultSet.CONCUR_READ_ONLY
:该常量指示ResultSet
是只读
的并发模式(默认)。ResultSet.CONCUR_UPDATABLE
:该常量指示ResultSet
是可更新
的并发模式。
注意:TYPE_SCROLL_INSENSITIVE
、 TYPE_SCROLL_SENSITIVE
两个常量的作用需要底层数据库驱动的支持,对于有些数据库驱动来说,这两个常量并没有太大的区别。
下面代码通过这两个参数创建了一个PreparedStatement
对象,由该对象生成的ResultSet
对象将是可滚动、可更新的结果集。
需要指出的是,可更新的结果集还需要满足如下两个条件。
- 所有数据都应该来自一个表。
- 选出的数据集必须包含主键列。
通过该PreparedStatement
创建的ResultSet
就是可滚动、可更新的,程序可调用ResultSet
的updateXxx(int columnIndex, Xxx value)
方法来修改记录指针所指向的行的特定列的值,最后调用ResultSet
的updateRow()
方法来提交修改。Java 8
为ResultSet
添加了:
updateObject(String columnLabel,Object x, SQLType targetSqlType)
和updateObject(int columnIndex, Object x, SQLType targetsqlType)
这两个默认方法,这两个方法可以直接用Object
来修改记录指针所指记录、特定列的值,其中SQLType
用于指定该数据列的类型.但目前最新的MySQL
驱动暂不支持该方法。
下面程序示范了这种创建可滚动、可更新的结果集的方法。
1 | import java.util.*; |
运行上面程序,将会看到student_table
表中的记录被倒过来输出了,因为是从最大记录行开始输出的。而且当程序运行结束后, student_table
表中所有记录的student_name
列的值都被修改了。
运行效果如下:
1 | 7 赵六 3 |
注意:
如果要创建可更新的结果集,则使用查询语句查询的数据通常只能来自于一个数据表,而且查询结果集中的数据列必须包含主键列,否则将会引起更新失败