結果集定制

現代 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 的官方文檔。