JDBC Statement 對象

2018-09-28 19:59 更新

Statement 對象

一旦我們獲得了數(shù)據(jù)庫的連接,我們就可以和數(shù)據(jù)庫進(jìn)行交互。JDBC 的 Statement,CallableStatement 和 PreparedStatement 接口定義的方法和屬性,可以讓你發(fā)送 SQL 命令或 PL/SQL 命令到數(shù)據(jù)庫,并從你的數(shù)據(jù)庫接收數(shù)據(jù)。

在數(shù)據(jù)庫中,它們還定義了幫助 Java 和 SQL 數(shù)據(jù)類型之間轉(zhuǎn)換數(shù)據(jù)差異的方法。

下表提供了每個接口的用途概要,根據(jù)實(shí)際目的決定使用哪個接口。

接口推薦使用
Statement可以正常訪問數(shù)據(jù)庫,適用于運(yùn)行靜態(tài) SQL 語句。 Statement 接口不接受參數(shù)。
PreparedStatement計(jì)劃多次使用 SQL 語句, PreparedStatement 接口運(yùn)行時接受輸入的參數(shù)。
CallableStatement適用于當(dāng)你要訪問數(shù)據(jù)庫存儲過程的時候, CallableStatement 接口運(yùn)行時也接受輸入的參數(shù)。

Statement 對象

創(chuàng)建 Statement 對象

在你準(zhǔn)備使用 Statement 對象執(zhí)行 SQL 語句之前,你需要使用 Connection 對象的 createStatement() 方法創(chuàng)建一個,如下面的示例所示-

Statement stmt = null;
try {
   stmt = conn.createStatement( );
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

當(dāng)你創(chuàng)建了一個 Statement 對象之后,你可以用它的三個執(zhí)行方法的任一方法來執(zhí)行 SQL 語句。

  • boolean execute(String SQL) : 如果 ResultSet 對象可以被檢索,則返回的布爾值為 true ,否則返回 false 。當(dāng)你需要使用真正的動態(tài) SQL 時,可以使用這個方法來執(zhí)行 SQL DDL 語句。

  • int executeUpdate(String SQL) : 返回執(zhí)行 SQL 語句影響的行的數(shù)目。使用該方法來執(zhí)行 SQL 語句,是希望得到一些受影響的行的數(shù)目,例如,INSERT,UPDATE 或 DELETE 語句。

  • ResultSet executeQuery(String SQL) : 返回一個 ResultSet 對象。當(dāng)你希望得到一個結(jié)果集時使用該方法,就像你使用一個 SELECT 語句。

關(guān)閉 Statement 對象

正如你關(guān)閉一個 Connection 對象來節(jié)約數(shù)據(jù)庫資源,出于同樣的原因你也應(yīng)該關(guān)閉 Statement 對象。

簡單的調(diào)用 close() 方法就可以完成這項(xiàng)工作。如果你關(guān)閉了 Connection 對象,那么它也會關(guān)閉 Statement 對象。然而,你應(yīng)該始終明確關(guān)閉 Statement 對象,以確保真正的清除。

Statement stmt = null;
try {
   stmt = conn.createStatement( );
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   stmt.close();
}

為了更好地理解,我們建議你研究學(xué)習(xí) Statement 示例教程。

PreparedStatement 對象

PreparedStatement 接口擴(kuò)展了 Statement 接口,它讓你用一個常用的 Statement 對象增加幾個高級功能。

這個 statement 對象可以提供靈活多變的動態(tài)參數(shù)。

創(chuàng)建 PreparedStatement 對象

PreparedStatement pstmt = null;
try {
   String SQL = "Update Employees SET age = ? WHERE id = ?";
   pstmt = conn.prepareStatement(SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

JDBC 中所有的參數(shù)都被用 ? 符號表示,這是已知的參數(shù)標(biāo)記。在執(zhí)行 SQL 語句之前,你必須賦予每一個參數(shù)確切的數(shù)值。

setXXX() 方法將值綁定到參數(shù),其中 XXX 表示你希望綁定到輸入?yún)?shù)的 Java 數(shù)據(jù)類型。如果你忘了賦予值,你將收到一個 SQLException。

每個參數(shù)標(biāo)記映射它的序號位置。第一標(biāo)記表示位置 1 ,下一個位置為 2 等等。這種方法不同于 Java 數(shù)組索引,它是從 0 開始的。

所有的 Statement對象 的方法都與數(shù)據(jù)庫交互,(a) execute(),(b) executeQuery(),及 (c) executeUpdate() 也能被 PreparedStatement 對象引用。然而,這些方法被 SQL 語句修改后是可以輸入?yún)?shù)的。

關(guān)閉 PreparedStatement 對象

正如你關(guān)閉一個 Statement 對象,出于同樣的原因,你也應(yīng)該關(guān)閉 PreparedStatement 對象。

簡單的調(diào)用 close() 方法可以完成這項(xiàng)工作。如果你關(guān)閉了 Connection 對象,那么它也會關(guān)閉 PreparedStatement 對象。然而,你應(yīng)該始終明確關(guān)閉 PreparedStatement 對象,以確保真正的清除。

PreparedStatement pstmt = null;
try {
   String SQL = "Update Employees SET age = ? WHERE id = ?";
   pstmt = conn.prepareStatement(SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   pstmt.close();
}

CallableStatement 對象

正如一個 Connection 對象可以創(chuàng)建 Statement 對象和 PreparedStatement 對象,它也可以創(chuàng)建被用來執(zhí)行調(diào)用數(shù)據(jù)庫存儲過程的 CallableStatement 對象。

創(chuàng)建 CallableStatement 對象

假如你需要執(zhí)行以下的 Oracle 存儲過程-

CREATE OR REPLACE PROCEDURE getEmpName 
   (EMP_ID IN NUMBER, EMP_FIRST OUT VARCHAR) AS
BEGIN
   SELECT first INTO EMP_FIRST
   FROM Employees
   WHERE ID = EMP_ID;
END;

注意:上面的存儲過程已經(jīng)寫入到 Oracle 數(shù)據(jù)庫中,但我們正在使用 MySQL 數(shù)據(jù)庫,那么我們可以在 MySQL 的 EMP 數(shù)據(jù)庫中創(chuàng)建相同的存儲過程。

DELIMITER $$

DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$
CREATE PROCEDURE `EMP`.`getEmpName` 
   (IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255))
BEGIN
   SELECT first INTO EMP_FIRST
   FROM Employees
   WHERE ID = EMP_ID;
END $$

DELIMITER ;

三種類型的參數(shù)有:IN,OUT 和 INOUT。PreparedStatement 對象只使用 IN 參數(shù)。CallableStatement 對象可以使用所有的三個參數(shù)。

這里是每個參數(shù)的定義-

參數(shù)描述
IN在 SQL 語句創(chuàng)建的時候該參數(shù)是未知的。你可以用 setXXX() 方法將值綁定到IN參數(shù)中。
OUT該參數(shù)由 SQL 語句的返回值提供。你可以用 getXXX() 方法獲取 OUT 參數(shù)的值。
INOUT該參數(shù)同時提供輸入輸出的值。你可以用 setXXX() 方法將值綁定參數(shù),并且用 getXXX() 方法獲取值。

下面的代碼片段展示了基于存儲過程如何使用 Connection.prepareCall() 方法來實(shí)例化 CallableStatement 對象。

CallableStatement cstmt = null;
try {
   String SQL = "{call getEmpName (?, ?)}";
   cstmt = conn.prepareCall (SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

SQL 的 String 變量使用參數(shù)占位符表示存儲過程。

使用 CallableStatement 對象就像使用 PreparedStatement 對象。你必須在執(zhí)行該語句之前將值綁定到所有的參數(shù),否則你將收到一個 SQL 異常。

如果你有 IN 參數(shù),只要使用適用于 PreparedStatement 對象相同的規(guī)則和技巧;使用 setXXX() 方法綁定對應(yīng)的 Java 數(shù)據(jù)類型。

當(dāng)你使用 OUT 和 INOUT 參數(shù)時,你就必須使用額外的 CallableStatement 方法 - registerOutParameter()。 registerOutParameter() 方法綁定 JDBC 數(shù)據(jù)類型,該數(shù)據(jù)是存儲過程返回的值。

一旦你調(diào)用存儲過程,你可以用適當(dāng)?shù)?getXXX() 方法來獲取 OUT 參數(shù)的值。這個方法將檢索到的 SQL 類型映射成 Java 數(shù)據(jù)類型。

關(guān)閉 CallableStatement 對象

正如你關(guān)閉其它的 Statement 對象,出于同樣的原因,你也應(yīng)該關(guān)閉 PreparedStatement 對象。

簡單的調(diào)用 close() 方法可以完成這項(xiàng)工作。如果你關(guān)閉了 Connection 對象,那么它也會關(guān)閉 CallableStatement 對象。然而,你應(yīng)該始終明確關(guān)閉 CallableStatement 對象,以確保真正的清除。

CallableStatement cstmt = null;
try {
   String SQL = "{call getEmpName (?, ?)}";
   cstmt = conn.prepareCall (SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   cstmt.close();
}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號