结果集定制

现代 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)方法根据给定类型是否受支持返回truefalse 。

在撰写本文时,存在三种类型的 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)方法根据是否支持给定的并发模式返回truefalse 。

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 的官方文档。