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

JDBC 基礎教學:Statement 介面家族完整指南——建立、執行、SQL 轉義語法與多結果處理

     編輯:Java 相關知識

前言:三大 Statement 分工協作

Statement 介面家族封裝 SQL 執行邏輯:

  • Statement:簡單 SQL (無參數)
  • PreparedStatement (繼承 Statement):預編譯 SQL,支援 IN 參數,重複執行高效
  • CallableStatement (繼承 PreparedStatement):呼叫預存程序,支援 IN/OUT/INOUT 參數

一、建立與執行 Statement

Connection con = DriverManager.getConnection(url, "sunny", "");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table2");

三種執行方法選擇指南

方法適用 SQL回傳值
executeQuerySELECT 等產生單一結果集ResultSet
executeUpdateINSERT/UPDATE/DELETE、DDL (CREATE/DROP TABLE)更新列數 (int),DDL 回傳 0
execute多結果集/更新計數、動態 SQL、預存程序boolean (true=有結果集)

重要:所有執行方法會關閉該 Statement 當前開啟的 ResultSet,重新執行前必須處理完畢。

PreparedStatement/CallableStatement 版本**不接受 SQL 字串參數** (已預編譯),傳入查詢參數會拋出 SQLException。

二、語句完成與關閉

  • 自動提交模式下,語句完成 (執行完且結果返回) 即自動提交/回滾。
  • executeQuery:讀完所有列視為完成。executeUpdate:執行即完成。execute:讀完所有結果集/更新計數始完成。
  • 預存程序內部語句視為獨立或複合語句視 DBMS 而定,影響自動提交時機。
  • 良好習慣:stmt.close() 顯式釋放 DBMS 資源,雖 GC 會自動回收。

三、SQL 轉義語法:跨 DBMS 可移植功能

語法:{keyword ... parameters ...}。驅動掃描轉義子句並轉換為 DBMS 原生語法。

1. LIKE 轉義字元 {escape '字元'}

% (匹配任意長度)、_ (匹配單字元) 為 LIKE 通配符。需字面匹配時前置轉義字元:

stmt.executeQuery("SELECT name FROM Identifiers WHERE Id LIKE '\\_%' {escape '\\'}");

2. 標量函數 {fn 函數名(參數)}

數值、字串、時間、日期、系統、轉換函數。驅動映射至 DBMS 原生語法或直接實作。範例:

{fn concat('Hot', 'Java')}  -- 字串連接
{fn user()}                  -- 當前資料庫使用者

支援函數列表可透過 DatabaseMetaData.getNumericFunctions()、getStringFunctions() 等查詢。

3. 日期時間字面值 (ISO 格式)

  • 日期:{d 'yyyy-MM-dd'} → 驅動轉換 (如 Oracle '28-FEB-99')
  • 時間:{t 'HH:mm:ss'}
  • 時間戳記:{ts 'yyyy-MM-dd HH:mm:ss.f...'} (小數秒可省略)

4. 預存程序呼叫

{call procedure_name(?, ?)}
{? = call procedure_name(?, ?)}  -- 有回傳值

參數可為字面值或 ? 佔位符。DatabaseMetaData.supportsStoredProcedures() 檢查支援性。

5. 外部聯結 {oj outer-join}

outer-join := table LEFT OUTER JOIN {table | outer-join} ON search-condition。進階功能,支援度可查 supportsOuterJoins、supportsFullOuterJoins、supportsLimitedOuterJoins。

6. 轉義處理開關

stmt.setEscapeProcessing(boolean) 預設開啟。效能極度敏感時可關閉。**不適用於 PreparedStatement** (可能預先發送至資料庫)。

四、進階:execute() 處理多結果集

僅用於預存程序或動態 SQL 可能回傳多結果集/更新計數組合的罕見情況。

處理流程

  1. 呼叫 execute(sql),回傳 true (首結果為 ResultSet) 或 false (首結果為更新計數/DDL)。
  2. 若 true:getResultSet() 取得首結果集 → 處理 → getMoreResults() 移至下一結果。
  3. 若 false:getUpdateCount() 取得首更新計數 → getMoreResults() 移至下一結果。
  4. getMoreResults() 回傳 true (下一為 ResultSet) 或 false (下一為更新計數/無結果)。
  5. 判斷「無更多結果」條件:(getResultSet()==null && getUpdateCount()==-1) 或 (getMoreResults()==false && getUpdateCount()==-1)。

通用處理範本

stmt.execute(queryStringWithUnknownResults);
while (true) {
    int rowCount = stmt.getUpdateCount();
    if (rowCount > 0) {  // 更新計數
        System.out.println("Rows changed = " + rowCount);
        stmt.getMoreResults();
        continue;
    }
    if (rowCount == 0) {  // DDL 或 0 更新
        System.out.println("No rows changed or DDL command");
        stmt.getMoreResults();
        continue;
    }
    // rowCount == -1:可能為 ResultSet 或無結果
    ResultSet rs = stmt.getResultSet();
    if (rs != null) {
        // 使用 ResultSetMetaData 解析欄位
        while (rs.next()) { /* 處理列 */ }
    } else {
        break;  // 無更多結果
    }
}

結語

掌握三大 Statement 分工、SQL 轉義語法實現跨資料庫可移植性、多結果集處理邏輯,能應對從簡單查詢到複雜預存程序的各類資料庫操作場景。善用 PreparedStatement 提升重複執行效能,謹慎使用 execute() 處理未知結果結構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved