13.5 管理结果集 13.5.1 可滚动,可更新的结果集
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 |
注意:
如果要创建可更新的结果集,则使用查询语句查询的数据通常只能来自于一个数据表,而且查询结果集中的数据列必须包含主键列,否则将会引起更新失败