首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JDBC 進階特性深度解析:標量函數、可捲動/可更新 ResultSet、RowSet 與批量更新實戰

     編輯:Java 相關知識

許多開發者僅將 JDBC 視為 ORM 底層,實則 JDBC 2.0~4.0 引入的進階特性能直接解決可擴展性與開發效率痛點。本文系統梳理 5 大核心進階功能。

1. 標量函數:跨資料庫可移植 SQL

JDBC 規範定義標準函數語法 `{fn ...}`,驅動程式負責轉譯為目標資料庫方言。範例:

ResultSet rs = stmt.executeQuery("{CURRENT_DATE()}"); // 取得當前日期
ResultSet rs = stmt.executeQuery("{CONCAT(first_name, ' ', last_name)}"); // 字串串接

透過 `DatabaseMetaData` 查詢支援清單:

String numericFns = dbmd.getNumericFunctions();   // 數值函數
String stringFns  = dbmd.getStringFunctions();    // 字串函數
String systemFns  = dbmd.getSystemFunctions();    // 系統函數
String timeFns    = dbmd.getTimeDateFunctions();  // 時間日期函數

回傳逗號分隔字串,`split(",")` 即得可測試清單。

2. 可捲動 ResultSet:雙向游標

建立時指定類型:

Statement stmt = con.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE,  // 可捲動,不反映他人提交的變更
    ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery("SELECT * FROM whatever");

三種捲動類型:

  • `TYPE_FORWARD_ONLY`:預設,單向流
  • `TYPE_SCROLL_INSENSITIVE`:雙向,快照語義(最常用)
  • `TYPE_SCROLL_SENSITIVE`:雙向,即時反映資料變更

導航方法:`previous()`、`first()`、`last()`、`absolute(n)`、`relative(n)`、`getRow()`、`setFetchDirection()`。

3. 可更新 ResultSet:就地修改回寫

第二參數指定 `CONCUR_UPDATABLE`:

Statement stmt = con.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE,
    ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT * FROM lineitem WHERE id=1");
rs.first();
rs.updateFloat("PRICE", 121.45f);
if (userSaidOK) rs.updateRow(); else rs.cancelRowUpdates();

新增列:`moveToInsertRow()` → `updateXxx()` → `insertRow()`。刪除:`deleteRow()`。同樣適用於 `PreparedStatement`(防 SQL 注入)。

4. RowSet:離線操作的 JavaBeans 封裝

解決可捲動/可更新需長連線的擴展性難題。五種介面實作:

類型連線模式特色
JdbcRowSet連線ResultSet 直接封裝
CachedRowSet離線基礎離線實作
WebRowSet離線支援 XML 序列化/反序列化
JoinRowSet離線無連線執行 SQL JOIN
FilteredRowSet離線客戶端進一步過濾

用法:

CachedRowSet crs = new CachedRowSetImpl();
crs.populate(rs); // 從 ResultSet 填充
// 斷線後仍可捲動、更新、插入、刪除
crs.acceptChanges(); // 重連時批量同步回資料庫

RowSet 為完整 JavaBeans,支援屬性設定(URL、用戶、密碼、DataSource、Command)、事件監聽、自主執行 `execute()`。

5. 批量更新:單次網路往返執行多條 SQL

驅動支援檢查:`dbmd.supportsBatchUpdates()`。流程:

conn.setAutoCommit(false);
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO lineitems VALUES(?,?,?,?)");
for (LineItem item : items) {
    pstmt.setInt(1, item.id);
    pstmt.setString(2, item.sku);
    pstmt.setFloat(3, item.price);
    pstmt.setBoolean(4, item.active);
    pstmt.addBatch();
}
int[] updateCounts = pstmt.executeBatch(); // 一次性送出
conn.commit();
conn.setAutoCommit(true);

回傳 `int[]` 對應各條 `executeUpdate()` 結果。異常拋 `BatchUpdateException`,驅動行為不一(可能繼續/停止),需實測驗證。

選型建議

  • 高擴展性系統:優先 RowSet(離線)、批量更新(減少網路交互)、標量函數(可移植)
  • 中低併發、需即時一致性:可捲動/可更新 ResultSet 可接受
  • 避免:長事務中持有可更新 ResultSet 造成鎖爭用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved