JDBC Statement 對(duì)象

2018-09-28 19:59 更新

Statement 對(duì)象

一旦我們獲得了數(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ù)差異的方法。

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

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

Statement 對(duì)象

創(chuàng)建 Statement 對(duì)象

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

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

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

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

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

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

關(guān)閉 Statement 對(duì)象

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

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

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

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

PreparedStatement 對(duì)象

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

這個(gè) statement 對(duì)象可以提供靈活多變的動(dòng)態(tài)參數(shù)。

創(chuàng)建 PreparedStatement 對(duì)象

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

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

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

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

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

關(guān)閉 PreparedStatement 對(duì)象

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

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

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

CallableStatement 對(duì)象

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

創(chuàng)建 CallableStatement 對(duì)象

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

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;

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

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 對(duì)象只使用 IN 參數(shù)。CallableStatement 對(duì)象可以使用所有的三個(gè)參數(shù)。

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

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

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

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

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

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

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

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

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

關(guān)閉 CallableStatement 對(duì)象

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

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

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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)