jdbc statement, preparedstatement 和 callablestatement
獲得了數(shù)據(jù)庫(kù)連接后,我們就可以與數(shù)據(jù)庫(kù)進(jìn)行交互了。jdbc 中的 statement, callablestatement 和 preparedstatement 三個(gè)對(duì)象,定義了一系列的方法和屬性,可以用來(lái)向數(shù)據(jù)庫(kù)發(fā)送 sql 命令,接收數(shù)據(jù)。
接口 | 使用說(shuō)明 |
---|---|
statement | 運(yùn)行靜態(tài) sql 語(yǔ)句時(shí)使用,statement 不能接收輸入?yún)?shù)。 |
preparedstatement | 當(dāng)計(jì)劃多次使用某條 sql 語(yǔ)句時(shí)使用,并且 preparedstatement 可以接收輸入?yún)?shù)。 |
callablestatement | 用來(lái)調(diào)用數(shù)據(jù)庫(kù)的存儲(chǔ)過(guò)程,callablestatement 可以接收輸入?yún)?shù)。 |
1. statement 對(duì)象
1)創(chuàng)建 statement 對(duì)象
statement 對(duì)象由 connection 對(duì)象的 createstatement( ) 方法創(chuàng)建,用來(lái)執(zhí)行靜態(tài) sql 語(yǔ)句,如下所示:
statement stmt = null; try { stmt = conn.createstatement( ); . . . } catch (sqlexception e) { . . . } finally { . . . }
一旦創(chuàng)建了一個(gè) statement 對(duì)象,然后可以它的三個(gè)執(zhí)行方法之一執(zhí)行 sql 語(yǔ)句。
- boolean execute(string sql) :這個(gè)方法常用來(lái)執(zhí)行 sql ddl 語(yǔ)句。
- int executeupdate(string sql) :返回 sql 語(yǔ)句執(zhí)行時(shí)受影響的行數(shù),常用來(lái)執(zhí)行 insert,update 或 delete 語(yǔ)句。
- resultset executequery(string sql) : 返回 resultset 對(duì)象。常用來(lái)執(zhí)行 select 語(yǔ)句,會(huì)得到一個(gè)結(jié)果集 resultset。
2)關(guān)閉 statement 對(duì)象
正如關(guān)閉一個(gè) connection 對(duì)象來(lái)釋放數(shù)據(jù)庫(kù)資源,出于同樣的原因,也應(yīng)該關(guān)閉 statement 對(duì)象。
使用 close() 方法關(guān)閉 statement。
statement stmt = null; try { stmt = conn.createstatement( ); . . . } catch (sqlexception e) { . . . } finally { stmt.close(); }
2. preparedstatement 對(duì)象
preparedstatement 接口擴(kuò)展了 statement 接口,給 statement 對(duì)象增加幾個(gè)高級(jí)功能。
它對(duì) sql 語(yǔ)句進(jìn)行預(yù)編譯,效率更高。另外,可以接收動(dòng)態(tài)參數(shù),避免 statement 中的 sql 注入問(wèn)題。
1)創(chuàng)建 preparedstatement 對(duì)象
preparedstatement pstmt = null; try { string sql = "update employees set age = ? where id = ?"; pstmt = conn.preparestatement(sql); pstmt.setint(1, 22); . . . } catch (sqlexception e) { . . . } finally { . . . }
在 jdbc 中參數(shù)使用 ?代表,在執(zhí)行 sql 語(yǔ)句之前,必須提供每一個(gè)參數(shù)的值。
setxxx() 方法將值綁定到參數(shù),其中 xxx 表示希望綁定到輸入?yún)?shù)值的 java 數(shù)據(jù)類(lèi)型。如果忘了提供值,將收到一個(gè)sqlexception。
每個(gè)參數(shù)標(biāo)記是由它的序號(hào)位置引用。第一標(biāo)記表示位置 1,下一個(gè)位置為 2 等等。這種方法不同于 java 數(shù)組索引,以 0 開(kāi)始。
2)關(guān)閉 preparedstatement 對(duì)象
正如關(guān)閉一個(gè) connection 對(duì)象來(lái)釋放數(shù)據(jù)庫(kù)資源,出于同樣的原因,也應(yīng)該關(guān)閉 preparedstatement 對(duì)象。
使用 close() 方法關(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(); }
3. callablestatement 對(duì)象
正如一個(gè)connection對(duì)象創(chuàng)建statement和preparedstatement對(duì)象,它也創(chuàng)造了callablestatement對(duì)象這將被用來(lái)執(zhí)行調(diào)用數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程。
1)創(chuàng)建 callablestatement 對(duì)象
假設(shè)需要執(zhí)行以下 oracle 存儲(chǔ)過(guò)程:
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ǔ)過(guò)程有三種類(lèi)型的參數(shù):in,out和inout。 preparedstatement對(duì)象只使用in參數(shù)。 callablestatement對(duì)象可以使用所有三個(gè)。
這里是每個(gè)的定義:
參數(shù) | 描述 |
---|---|
in | 它的值是在創(chuàng)建sql語(yǔ)句時(shí)未知的參數(shù)。將值綁定到與 setxxx() 方法的參數(shù)。 |
out | 其值由它返回的sql語(yǔ)句提供的參數(shù)。從 out 參數(shù)的 getxxx() 方法檢索值。 |
inout | 同時(shí)提供輸入和輸出值的參數(shù)。綁定變量使用 setxxx() 方法,使用 getxxx() 方法檢索值。 |
下面的代碼顯示了使用 connection.preparecall() 方法獲得存儲(chǔ)過(guò)程 callablestatement 對(duì)象:
callablestatement cstmt = null; try { string sql = "{call getempname (?, ?)}"; cstmt = conn.preparecall (sql); . . . } catch (sqlexception e) { . . . } finally { . . . }
sql 表示存儲(chǔ)過(guò)程,里面使用了參數(shù)占位符。
使用 callablestatement 對(duì)象是就像使用 preparedstatement 對(duì)象,執(zhí)行該語(yǔ)句之前,必須將值綁定到所有的參數(shù),否則將收到一個(gè) sqlexception。
如果有 in 參數(shù),只要按照 preparedstatement 對(duì)象相同的規(guī)則,使用 setxxx() 方法綁定的 java 數(shù)據(jù)類(lèi)型。
當(dāng)使用 out 和 inout 參數(shù)就必須采用額外的 callablestatement 及 registeroutparameter() 方法。registeroutparameter() 方法綁定數(shù)據(jù)類(lèi)型到存儲(chǔ)過(guò)的返回值。
2)關(guān)閉 callablestatement 對(duì)象
正如關(guān)閉其他 statement 對(duì)象,出于同樣的原因,也應(yīng)該關(guān)閉 callablestatement 對(duì)象。
正如關(guān)閉一個(gè) connection 對(duì)象來(lái)釋放數(shù)據(jù)庫(kù)資源,出于同樣的原因,也應(yīng)該關(guān)閉 callablestatementv 對(duì)象。
使用 close() 方法關(guān)閉 callablestatement。
callablestatement cstmt = null; try { string sql = "{call getempname (?, ?)}"; cstmt = conn.preparecall (sql); . . . } catch (sqlexception e) { . . . } finally { cstmt.close(); }