结果集定制
现代 JDBC API 允许您极大地自定义对象。陈述和结果集. 例如,使用结果集您可以更改数据库中的行。
在创建语句对象时,我们可以将一堆我们的愿望传递给它。这些愿望可以分为三类:
- 底座连接型
- 并发访问控制
- 持久性和事务
创建对象时可以传递这些参数陈述或者PreparedStatement. 例子:
Statement statement = connection.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY,
ResultSet.CLOSE_CURSORS_OVER_COMMIT );
PreparedStatement statement = connection.prepareStatement(sql,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY,
ResultSet.CLOSE_CURSORS_OVER_COMMIT);
我们不会深入研究这些东西,但我想让你知道,如果你在别人的代码中遇到类似的东西,这是可能的。
结果集类型
ResultSet 可以是特定类型。该类型定义了 ResultSet 的一些特征和功能。
并非所有类型都受所有数据库和 JDBC 驱动程序支持。您必须检查您的数据库和 JDBC 驱动程序,看它是否支持您要使用的类型。DatabaseMetaData.supportsResultSetType(int type)方法根据给定类型是否受支持返回true或false 。
在撰写本文时,存在三种类型的 ResultSet:
- 结果集.TYPE_FORWARD_ONLY
- 结果集.TYPE_SCROLL_INSENSITIVE
- 结果集.TYPE_SCROLL_SENSITIVE
默认类型是 TYPE_FORWARD_ONLY。
TYPE_FORWARD_ONLY表示ResultSet 只能向前移动。也就是说,你只能从第1行、第2行、第3行等开始移动。在一个ResultSet中,你不能向后移动:你不能在读取第10行后从第9行读取数据。
TYPE_SCROLL_INSENSITIVE表示 ResultSet 可以向前或向后移动(滚动)。您还可以移动到相对于当前位置的位置,或移动到绝对位置。
当 ResultSet 打开时,这种类型的 ResultSet对基础数据源的更改不敏感。也就是说,如果 ResultSet 中的条目在数据库中被另一个线程或进程更改,它不会反映在已经打开的结果集这种类型的。
TYPE_SCROLL_SENSITIVE表示 ResultSet 可以向前或向后移动(滚动)。您还可以移动到相对于当前位置的位置,或移动到绝对位置。
当 ResultSet 打开时,此类型的 ResultSet对基础数据源中的更改很敏感。也就是说,如果 ResultSet 中的条目在数据库中被另一个线程或进程更改,它将反映在已经打开的结果集这种类型的。
并发
ResultSet 的并发性决定了 ResultSet 是可以更新还是只能读取。
一些数据库和 JDBC 驱动程序支持更新 ResultSet,但不是全部。DatabaseMetaData.supportsResultSetConcurrency(int concurrency)方法根据是否支持给定的并发模式返回true或false 。
ResultSet 可以具有两个并发级别之一:
- 结果集.CONCUR_READ_ONLY
- 结果集.CONCUR_UPDATABLE
CONCUR_READ_ONLY表示只能读取 ResultSet。
CONCUR_UPDATABLE表示可以读取和修改 ResultSet。
更改数据库中数据的示例
通过这些参数,您可以控制生成的 Statement 及其 ResultSet。
例如,您可以创建一个可更新的 ResultSet 并使用它来更改数据库。创建声明时,请务必遵守以下条件:
- 只指定了一张表
- 不包含 join 或 group by 子句
- 查询列必须包含主键
当满足上述条件时,更新后的ResultSet可用于更新数据库中的一个表。创建 Statement 对象时,需要指定以下参数:
Statement st = createStatement(Result.TYPE_SCROLL_INSENSITIVE, Result.CONCUR_UPDATABLE)
执行这样一条语句的结果是一个可更新的结果集。update方法是将ResultSet游标移动到要更新的行,然后调用updateXXX()方法。
updateXXX方法的工作方式与getXXX()方法类似。updateXXX()方法有两个参数。第一个是正在更新的列的编号,可以是列名或序列号。其次是需要更新的数据,这个数据类型必须和XXX一样。
要真正更新数据库中的行,您需要在 ResultSet 游标离开更改的行之前调用updateRow()方法,否则更改将不会进入数据库。
您还可以向表中添加新行:
首先,您需要将光标移动到一个空行。为此,请调用moveToInsertRow()方法。
然后您需要使用updateXXX()方法用数据填充该行。
然后您需要调用inserterRow()方法将行添加到基中。
最后,您需要通过调用moveToCurrentRow()方法返回光标。
重要的!并非所有 DBMS 都支持扩展语句的这些选项。如有问题,请参阅特定 DBMS 的官方文档。
GO TO FULL VERSION