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

JDBC 核心教程:PreparedStatement 預編譯與參數化查詢最佳實踐

     編輯:Java 相關知識

PreparedStatement 核心優勢

  1. 預編譯:SQL 語句發送 DBMS 編譯一次,多次執行無需重複解析優化,效能顯著優於 Statement。
  2. 參數化:? 佔位符防止 SQL 注入,型別安全,自動處理引號/轉義。
  3. 批次處理:支援 addBatch()/executeBatch() 大幅提升批量寫入效能。

建立與參數綁定

PreparedStatement pstmt = con.prepareStatement(
    "UPDATE table4 SET m = ? WHERE x = ?");

// 參數索引從 1 開始
pstmt.setLong(1, 123456789);  // 對應第一個 ?
pstmt.setLong(2, 100000000);  // 對應第二個 ?

重複執行與參數清除

設置參數後可多次執行,直到調用 clearParameters() 重置。自動提交模式下每次執行自動提交/回滾。

pstmt.setString(1, "Hi"); // 固定參數
for (int i = 0; i < 10; i++) {
    pstmt.setInt(2, i);   // 變動參數
    pstmt.executeUpdate();
}

前提:資料庫/驅動在提交後保持 Statement 開啟 (多數現代驅動支援),否則無法復用。

Java 型別與 JDBC 型別映射一致性

setXXX 方法名對應 Java 型別,驅動自動映射至標準 JDBC 型別 (參考 JDBC 規範 8.6.2 映射表)。

Java 型別setXXX 方法標準 JDBC 型別
shortsetShortSMALLINT
intsetIntINTEGER
longsetLongBIGINT
floatsetFloatREAL
doublesetDoubleDOUBLE
StringsetStringVARCHAR
byte[]setBytesVARBINARY
DatesetDateDATE
TimestampsetTimestampTIMESTAMP

開發者責任:確保 Java 型別映射的 JDBC 型別與資料庫欄位定義相容。如資料庫需 SMALLINT,用 setByte (TINYINT) 通常可隱式轉換,但嚴格匹配最安全。

三大執行方法 (無參數版)

  • executeQuery():返回 ResultSet (SELECT)。
  • executeUpdate():返回影響行數 (INSERT/UPDATE/DELETE/DDL)。
  • execute():通用執行,可能返回多結果集,需配合 getResultSet()/getUpdateCount()/getMoreResults() 處理。

禁用:Statement 版本的帶 SQL 字串重載方法 (executeQuery(sql) 等),會拋出異常或忽略預編譯優勢。

防 SQL 注入原理示範

// 不安全 - 字串拼接
stmt.executeUpdate("SELECT * FROM users WHERE name = '" + userInput + "'");
// 輸入: ' OR '1'='1 → 全表查詢

// 安全 - 參數化
pstmt = con.prepareStatement("SELECT * FROM users WHERE name = ?");
pstmt.setString(1, userInput); // 輸入被視為字面值,不解析 SQL

進階技巧

  • 生成鍵值獲取:prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) → getGeneratedKeys() 獲取自增主鍵。
  • 游標控制:prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY) 實現可捲動結果集。
  • 批次優化:關閉自動提交、addBatch 累積、executeBatch 一次性提交、捕獲 BatchUpdateException 處理部分失敗。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved