PreparedStatement 繼承自 Statement,具備兩大關鍵特性:
Statement。? 佔位符代表 IN 參數,執行前透過 setXXX 方法綁定具體值,有效防止 SQL 注入。PreparedStatement pstmt = con.prepareStatement(
"UPDATE table4 SET m = ? WHERE x = ?");
pstmt.setLong(1, 123456789);
pstmt.setLong(2, 100000000);
int rows = pstmt.executeUpdate();
參數索引從 1 開始。設定完成後可重複執行,直到呼叫 clearParameters() 清除。
pstmt.setString(1, "Hi");
for (int i = 0; i < 10; i++) {
pstmt.setInt(2, i);
pstmt.executeUpdate();
}
前提:資料庫/驅動程式在提交後仍保持陳述式開啟,否則無法發揮效能優勢。
setXXX 的 XXX 為 Java 型別,驅動程式會依標準映射轉為對應 JDBC 型別(如 short → SMALLINT)。開發者需確保 Java 型別映射的 JDBC 型別與資料庫欄位相容。為了最大可攜性,建議使用與目標 JDBC 型別完全對應的 Java 型別(如需 SMALLINT 請用 setShort 而非 setByte)。
setObject(int idx, Object val, int targetSqlType) 可顯式指定目標 JDBC 型別(java.sql.Types 常數),適用於:
若省略第三參數,驅動程式會依物件型別使用預設映射(參見 JDBC 規範 8.6.4 節對照表)。
setNull(int idx, int sqlType):必須指定 SQL 型別setXXX 傳入 Java null 同樣會送出 JDBC NULLsetObject 傳 null 時必須指定目標 SQL 型別對於超大 BLOB/CLOB 參數,可使用輸入流分塊傳送:
setBinaryStream(idx, InputStream, length):二進位位元組流setAsciiStream(idx, InputStream, length):ASCII 字元流setUnicodeStream(idx, InputStream, length):Unicode 字元流必須指定流總長度(某些資料庫需預知傳輸大小)。
File file = new File("/tmp/data");
try (InputStream fin = new FileInputStream(file)) {
PreparedStatement pstmt = con.prepareStatement(
"UPDATE Table5 SET stuff = ? WHERE index = 4");
pstmt.setBinaryStream(1, fin, file.length());
pstmt.executeUpdate();
}
執行時驅動程式會反覆讀取流內容直到 EOF。