PreparedStatement 接口繼承自 Statement,主要有兩大不同:
PreparedStatement 實例包含已編譯的 SQL 語句,這就是「預備好」的含義。SQL 語句可包含一個或多個 IN 參數,參數值在創建時不指定,而是用問號(?) 作為佔位符,執行前透過 setXXX 方法提供具體值。Statement,適合重複執行的 SQL,能提升效率。作為 Statement 子類,PreparedStatement 繼承其所有功能,並新增一整套 setXXX 方法用於設置參數值。三大執行方法 execute、executeQuery、executeUpdate 已修改為無需參數形式,原接受 SQL 字串的重載不應用於 PreparedStatement。
以下程式碼片段(con 為 Connection 物件)建立含兩個 IN 參數佔位符的 PreparedStatement:
PreparedStatement pstmt = con.prepareStatement("UPDATE table4 SET m = ? WHERE x = ?");
pstmt 物件包含 SQL 語句 "UPDATE table4 SET m = ? WHERE x = ?",已送往 DBMS 並準備好執行。
執行前必須為每個 ? 參數設置值,透過呼叫對應的 setXXX 方法,其中 XXX 為參數的 Java 型別。第一個參數為參數序數位置(從 1 起算),第二個參數為要設置的值。例如:
pstmt.setLong(1, 123456789);
pstmt.setLong(2, 100000000);
參數值一經設置,可重複執行該語句,直到呼叫 clearParameters 清除為止。在連線預設自動提交模式下,語句完成時自動提交或回滾。
若資料庫與驅動程式在提交後仍保持語句開啟,同一 PreparedStatement 可多次執行;否則以其替代 Statement 提升效能將無意義。以下範例示範設置兩個參數並執行 10 次:
pstmt.setString(1, "Hi");
for (int i = 0; i < 10; i++) {
pstmt.setInt(2, i);
int rowCount = pstmt.executeUpdate();
}
setXXX 中的 XXX 為 Java 型別,隱含對應的 JDBC 型別(一般 SQL 型別)。驅動程式會依 JDBC 規範映射表 將 Java 型別映射為 JDBC 型別並送往資料庫。例如:
pstmt.setShort(2, 44);
驅動程式將 44 作為 JDBC SMALLINT 送往資料庫,這是 Java short 的標準映射。
開發者須確保每個 IN 參數的 Java 型別映射後,與資料庫所需的 JDBC 型別相容。例如資料庫需要 SMALLINT,若使用 setByte 會送出 TINYINT,許多資料庫可自動轉型,但不保證所有情況皆適用。