JDBC Statements, PreparedStatement和CallableStatement語句
當獲得了與數據庫的連接後,就可以與數據庫進行交互了。 JDBC Statement
,CallableStatement
和PreparedStatement
接口定義了可用於發送SQL或PL/SQL命令,並從數據庫接收數據的方法和屬性。
它們還定義了有助於在Java和SQL數據類型的數據類型差異轉換的方法。
下表提供了每個接口定義,以及使用這些接口的目的的總結。
接口
推薦使用
Statement
用於對數據庫進行通用訪問,在運行時使用靜態SQL語句時很有用。 Statement
接口不能接受參數。
PreparedStatement
當計劃要多次使用SQL語句時使用。PreparedStatement
接口在運行時接受輸入參數。
CallableStatement
當想要訪問數據庫存儲過程時使用。CallableStatement
接口也可以接受運行時輸入參數。
1. Statement對象
1.1. 創建Statement對象
在使用Statement
對象執行SQL語句之前,需要使用Connection
對象的createStatement()
方法創建一個Statement
對象,如以下示例所示:
Statement stmt = null;
try {
stmt = conn.createStatement( );
. . .
}
catch (SQLException e) {
. . .
}
finally {
. . .
}
在創建Statement
對象後,可以使用它來執行一個SQL語句,它有三個執行方法可以執行。它們分別是 -
-
boolean execute (String SQL)
: 如果可以檢索到ResultSet
對象,則返回一個布爾值true
; 否則返回false
。使用此方法執行SQLDDL
語句或需要使用真正的動態SQL,可使用於執行創建數據庫,創建表的SQL語句等等。 -
int executeUpdate (String SQL):
返回受SQL語句執行影響的行數。使用此方法執行預期會影響多行的SQL語句,例如:INSERT
,UPDATE
或DELETE
語句。 -
ResultSet executeQuery(String SQL):
返回一個ResultSet
對象。 當您希望獲得結果集時,請使用此方法,就像使用SELECT
語句一樣。
1.2. 關閉Statement對象
就像關閉一個Connection
對象一樣,以保存數據庫資源一樣,由於同樣的原因,還應該關閉Statement
對象。
一個簡單的調用close()
方法將執行該作業(工作)。 如果先關閉Connection
對象,它也會關閉Statement
對象。 但是,應該始終顯式關閉Statement
對象,以確保正確的清理順序。
Statement stmt = null;
try {
stmt = conn.createStatement( );
. . .
}
catch (SQLException e) {
. . .
}
finally {
stmt.close();
}
爲了更好的理解,建議學習Statment示例教程 。
2. PreparedStatement對象
PreparedStatement
接口擴展了Statement
接口,它添加了比Statement
對象更好一些優點的功能。
此語句可以動態地提供/接受參數。
2.1 創建PreparedStatement對象
PreparedStatement pstmt = null;
try {
String SQL = "Update Employees SET age = ? WHERE id = ?";
pstmt = conn.prepareStatement(SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
. . .
}
JDBC中的所有參數都由 ?
符號作爲佔位符,這被稱爲參數標記。 在執行SQL語句之前,必須爲每個參數(佔位符)提供值。
setXXX()
方法將值綁定到參數,其中XXX
表示要綁定到輸入參數的值的Java數據類型。 如果忘記提供綁定值,則將會拋出一個SQLException
。
每個參數標記是它其順序位置引用。第一個標記表示位置1
,下一個位置2
等等。 該方法與Java數組索引不同(它不從0
開始)。
所有Statement
對象與數據庫交互的方法(a)execute()
,(b)executeQuery()
和(c)executeUpdate()
也可以用於PreparedStatement
對象。 但是,這些方法被修改爲可以使用輸入參數的SQL語句。
2.2. 關閉PreparedStatement對象
就像關閉Statement
對象一樣,由於同樣的原因(節省數據庫系統資源),也應該關閉PreparedStatement
對象。
簡單的調用close()
方法將執行關閉。 如果先關閉Connection
對象,它也會關閉PreparedStatement
對象。 但是,應該始終顯式關閉PreparedStatement
對象,以確保以正確順序清理資源。
PreparedStatement pstmt = null;
try {
String SQL = "Update Employees SET age = ? WHERE id = ?";
pstmt = conn.prepareStatement(SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
pstmt.close();
}
爲了更好的理解,建議學習PreparedStatement示例代碼 。
3. CallableStatement對象
類似Connection
對象創建Statement
和PreparedStatement
對象一樣,它還可以使用同樣的方式創建CallableStatement
對象,該對象將用於執行對數據庫存儲過程的調用。
3.1. 創建CallableStatement對象
假設需要執行以下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;
注意:上面的存儲過程是針對Oracle編寫的,但是如果您使用MySQL數據庫,可使用以下方式來編寫MySQL相同的存儲過程,如下在EMP數據庫中創建它 -
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 ;
存在三種類型的參數:IN
,OUT
和INOUT
。 PreparedStatement
對象只使用IN
參數。CallableStatement
對象可以使用上面三個參數類型。
以下是上面三種類型參數的定義 -
參數
描述
IN
創建SQL語句時其參數值是未知的。 使用setXXX()
方法將值綁定到IN
參數。
OUT
由SQL語句返回的參數值。可以使用getXXX()
方法從OUT參數中檢索值。
INOUT
提供輸入和輸出值的參數。使用setXXX()
方法綁定變量並使用getXXX()
方法檢索值。
以下代碼片段顯示瞭如何使用Connection.prepareCall()
方法根據上述存儲過程來實例化一個CallableStatement
對象 -
CallableStatement cstmt = null;
try {
String strSQL = "{call getEmpName (?, ?)}";
cstmt = conn.prepareCall (SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
. . .
}
String變量strSQL
表示存儲過程,帶有兩個參數佔位符。
使用CallableStatement
對象就像使用PreparedStatement
對象一樣。 在執行語句之前,必須將值綁定到所有參數,否則將拋出一個SQLException
異常。
如果有IN
參數,只需遵循適用於PreparedStatement
對象的相同規則和技術; 使用與綁定的Java數據類型相對應的setXXX()
方法。
使用OUT
和INOUT
參數時,必須使用一個額外的CallableStatement
對象方法registerOutParameter()
。 registerOutParameter()
方法將JDBC數據類型綁定到存儲過程並返回預期數據類型。
當調用存儲過程,可以使用適當的getXXX()
方法從OUT
參數中檢索該值。 此方法將檢索到的SQL類型的值轉換爲對應的Java數據類型。
關閉CallableStatement對象
就像關閉其他Statement
對象一樣,由於同樣的原因(節省數據庫系統資源),還應該關閉CallableStatement
對象。
簡單的調用close()
方法將執行關閉CallableStatemen
t對象。 如果先關閉Connection
對象,它也會關閉CallableStatement
對象。 但是,應該始終顯式關閉CallableStatement
對象,以確保按正確順序的清理資源。
CallableStatement cstmt = null;
try {
String SQL = "{call getEmpName (?, ?)}";
cstmt = conn.prepareCall (SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
cstmt.close();
}
爲了更好的理解,建議參考學習Callable示例代碼。