Stringsql = "SELECT * FROM People p WHERE p.id = ? AND p.name = ?";使用PreparedStatement的另一個(gè)優(yōu)點(diǎn)是字符串不是動(dòng)態(tài)創(chuàng)建的。下面是一個(gè)動(dòng)態(tài)創(chuàng)建字符串的例子:
PreparedStatement ps = connection.prepareStatement(sql);
ps.setInt(1,id);
ps.setString(2,name);
ResultSet rs = ps.execute();
Stringsql = "SELECT * FROM People p WHERE p.i = "+id;
|
這允許JVM(JavaVirtual Machine,Java虛擬機(jī))和驅(qū)動(dòng)/數(shù)據(jù)庫緩存語句和字符串并提高性能。
PreparedStatement也提供數(shù)據(jù)庫無關(guān)性。當(dāng)顯示聲明的SQL越少,那么潛在的SQL語句的數(shù)據(jù)庫依賴性就越小。
由于PreparedStatement具備很多優(yōu)點(diǎn),開發(fā)者可能通常都使用它,只有在完全是因?yàn)樾阅茉蚧蛘呤窃谝恍蠸QL語句中沒有變量的時(shí)候才使用通常的Statement。
發(fā)出查詢和處理結(jié)果
在任何你想向數(shù)據(jù)庫運(yùn)行一個(gè)SQL語句的時(shí)候, 你都需要一個(gè) Statement 或 PreparedStatement 實(shí)例。 一旦你擁有了一個(gè) Statement 或 PreparedStatement,你就可以 發(fā)出一個(gè)查詢。 這樣將返回一個(gè) ResultSet 實(shí)例, 在其內(nèi)部包含整個(gè)結(jié)果。 Example 31-1 演示了這個(gè)過程。
Example 31-1. 在 JDBC 里處理一個(gè)簡(jiǎn)單的查詢
這個(gè)例子將發(fā)出一個(gè)簡(jiǎn)單的查詢?nèi)缓笥靡粋€(gè) Statement打印出每行的第一個(gè)字段。
Statement st = db.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE columnfoo = 500");
while (rs.next()) {
System.out.print("Column 1 returned ");
System.out.println(rs.getString(1));
}
rs.close();
st.close();
這個(gè)例子將使用 PreparedStatement 發(fā)出和前面一樣的查詢,并且在查詢中制作數(shù)值。
int foovalue = 500;
PreparedStatement st = db.prepareStatement("SELECT * FROM mytable WHERE columnfoo = ?");
st.setInt(1, foovalue);
ResultSet rs = st.executeQuery();
while (rs.next()) {
System.out.print("Column 1 returned ");
System.out.println(rs.getString(1));
}
rs.close();
st.close();
在使用 Statement或 PreparedStatement接口時(shí)必須考慮下面的問題:
你可以將一個(gè) Statement或 PreparedStatement實(shí)例使用任意次。 你可以在打開一個(gè)聯(lián)接后馬上創(chuàng)建一個(gè) Statement 實(shí)例, 并且在聯(lián)接的生存期里使用之。 你必須記住每個(gè) Statement或 PreparedStatement只能存在一個(gè) ResultSet。
如果你需要在處理一個(gè) ResultSet的時(shí)候執(zhí)行一個(gè)查詢, 你只需要?jiǎng)?chuàng)建并且使用另外一個(gè) Statement。
如果你使用了 threads (線程),并且有幾個(gè)使用數(shù)據(jù)庫, 你對(duì)每個(gè)線程必須使用一個(gè)獨(dú)立的 Statement。 如果考慮使用線程, 請(qǐng)參考本文檔稍后的 Section 31.8 章節(jié), 因?yàn)檫@些內(nèi)容包含一些重要的信息。
在你用完 Statement 或者 PreparedStatement 之后,你應(yīng)該關(guān)閉它。
使用 ResultSet接口時(shí)必須考慮下面的問題:
在讀取任何數(shù)值的時(shí)候,你必須調(diào)用 next()。 如果還有結(jié)果則返回真(true),但更重要的是,它為處理準(zhǔn)備了數(shù)據(jù)行。
在 JDBC 規(guī)范里,你對(duì)一個(gè)字段應(yīng)該只訪問一次。 遵循這個(gè)規(guī)則是最安全的,不過目前 PostgreSQL 驅(qū)動(dòng)將允許你對(duì)一個(gè)字段訪問任意次。
一旦你結(jié)束對(duì)一個(gè) ResultSet 的處理,你必須對(duì)之調(diào)用 close()來關(guān)閉它。
一旦你使用那個(gè)創(chuàng)建 ResultSet的 Statement做另一個(gè)查詢請(qǐng)求, 當(dāng)前打開的 ResultSet 實(shí)例將自動(dòng)關(guān)閉。
目前的 ResultSet 是只讀的。 你不能通過 ResultSet 來更新數(shù)據(jù)。 如果你想更新數(shù)據(jù),那么你就需要使用普通的方法來做∶ 通過發(fā)出一條 SQL 更新語句。這么做是和 JDBC 規(guī)范兼容的,它并不要求驅(qū)動(dòng)提供可更新的結(jié)果集的支持。
聯(lián)系客服