該 PreparedStatement接口繼承Statement,并與之在兩方面有所不同:
PreparedStatement 執行個體包含已編譯的 SQL 語句。這就是使語句“準備好”。包含于 PreparedStatement 對象中的 SQL 語句可具有一個或多個 IN 參數。IN參數的值在 SQL 語句建立時未被指定。相反的,該語句為每個 IN 參數保留一個問号(“?”)作為占位符。每個問号的值必須在該語句執行之前,通過适當的setXXX 方法來提供。
由于 PreparedStatement 對象已預編譯過,是以其執行速度要快于 Statement 對象。是以,多次執行的 SQL 語句經常建立為 PreparedStatement 對象,以提高效率。
作為 Statement 的子類,PreparedStatement 繼承了 Statement 的所有功能。另外它還添加了一整套方法,用于設定發送給資料庫以取代 IN 參數占位符的值。同時,三種方法 execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要參數。這些方法的 Statement 形式(接受 SQL 語句參數的形式)不應該用于 PreparedStatement 對象。
Statement 接口提供了三種執行 SQL 語句的方法:executeQuery、executeUpdate 和 execute。使用哪一個方法由 SQL 語句所産生的内容決定。
方法executeQuery
用于産生單個結果集的語句,例如 SELECT 語句。 被使用最多的執行 SQL 語句的方法是 executeQuery。這個方法被用來執行 SELECT 語句,它幾乎是使用最多的 SQL 語句。
方法executeUpdate
用于執行 INSERT、UPDATE 或 DELETE 語句以及 SQL DDL(資料定義語言)語句,例如 CREATE TABLE 和 DROP TABLE。INSERT、UPDATE 或 DELETE 語句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的傳回值是一個整數,訓示受影響的行數(即更新計數)。對于 CREATE TABLE 或 DROP TABLE 等不操作行的語句,executeUpdate 的傳回值總為零。
使用executeUpdate方法是因為在 createTableCoffees 中的 SQL 語句是 DDL (資料定義語言)語句。建立表,改變表,删除表都是 DDL 語句的例子,要用 executeUpdate 方法來執行。你也可以從它的名字裡看出,方法 executeUpdate 也被用于執行更新表 SQL 語句。實際上,相對于建立表來說,executeUpdate 用于更新表的時間更多,因為表隻需要建立一次,但經常被更新。
方法execute:
用于執行傳回多個結果集、多個更新計數或二者組合的語句。因為多數程式員不會需要該進階功能
execute方法應該僅在語句能傳回多個ResultSet對象、多個更新計數或ResultSet對象與更新計數的組合時使用。當執行某個已存儲過程 或動态執行未知 SQL 字元串(即應用程式程式員在編譯時未知)時,有可能出現多個結果的情況,盡管這種情況很少見。
因為方法 execute 處理非正常情況,是以擷取其結果需要一些特殊處理并不足為怪。例如,假定已知某個過程傳回兩個結果集,則在使用方法 execute 執行該過程後,必須調用方法 getResultSet 獲得第一個結果集,然後調用适當的 getXXX 方法擷取其中的值。要獲得第二個結果集,需要先調用 getMoreResults 方法,然後再調用 getResultSet 方法。如果已知某個過程傳回兩個更新計數,則首先調用方法 getUpdateCount,然後調用 getMoreResults,并再次調用 getUpdateCount。
對于不知道傳回内容,則情況更為複雜。如果結果是 ResultSet 對象,則方法 execute 傳回 true;如果結果是 Java int,則傳回 false。如果傳回 int,則意味着結果是更新計數或執行的語句是 DDL 指令。在調用方法 execute 之後要做的第一件事情是調用 getResultSet 或 getUpdateCount。調用方法 getResultSet 可以獲得兩個或多個 ResultSet 對象中第一個對象;或調用方法 getUpdateCount 可以獲得兩個或多個更新計數中第一個更新計數的内容。
當 SQL 語句的結果不是結果集時,則方法 getResultSet 将傳回 null。這可能意味着結果是一個更新計數或沒有其它結果。在這種情況下,判斷 null 真正含義的唯一方法是調用方法 getUpdateCount,它将傳回一個整數。這個整數為調用語句所影響的行數;如果為 -1 則表示結果是結果集或沒有結果。如果方法 getResultSet 已傳回 null(表示結果不是 ResultSet 對象),則傳回值 -1 表示沒有其它結果。也就是說,當下列條件為真時表示沒有結果(或沒有其它結果):
((stmt.getResultSet() == null) && (stmt.getUpdateCount() == -1))
如果已經調用方法 getResultSet 并處理了它傳回的 ResultSet 對象,則有必要調用方法 getMoreResults 以确定是否有其它結果集或更新計數。如果 getMoreResults 傳回 true,則需要再次調用 getResultSet 來檢索下一個結果集。如上所述,如果 getResultSet 傳回 null,則需要調用 getUpdateCount 來檢查 null 是表示結果為更新計數還是表示沒有其它結果。
當 getMoreResults 傳回 false 時,它表示該 SQL 語句傳回一個更新計數或沒有其它結果。是以需要調用方法 getUpdateCount 來檢查它是哪一種情況。在這種情況下,當下列條件為真時表示沒有其它結果:
((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1))
下面的代碼示範了一種方法用來确認已通路調用方法 execute 所産生的全部結果集和更新計數:
stmt.execute(queryStringWithUnknownResults);
while (true) {
int rowCount = stmt.getUpdateCount();
if (rowCount > 0) { // 它是更新計數
System.out.println("Rows changed = " + count);
stmt.getMoreResults();
continue;
}
if (rowCount == 0) { // DDL 指令或 0 個更新
System.out.println(" No rows changed or statement was DDL
command");
stmt.getMoreResults();
continue;
}
// 執行到這裡,證明有一個結果集
// 或沒有其它結果
ResultSet rs = stmt.getResultSet;
if (rs != null) {
. . . // 使用中繼資料獲得關于結果集列的資訊
while (rs.next()) {
. . . // 處理結果
stmt.getMoreResults();
continue;
}
break; // 沒有其它結果