2008-12-23 90 views
22

我想知道我們是否可以重複使用相同的Statement對象來執行多個查詢。或者,我們應該爲不同的查詢創建一個新的聲明。Java語句對象重用?

例如,

Connection con = getDBConnection(); 
Statement st1 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); 
int i = st1.executeUpdate("update tbl_domu set domU_status=1 where domU_id=" + dom_U_id); 
Statement st2 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); 
String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime()); 
int j = st2.executeUpdate("insert into tbl_domU_action_history values('" + dom_U_name + "', 1, '" + date + "')"); 

在上述情況下,有在使用相同的語句ST1爲兩個的executeUpdate()查詢的任何危害?我可以對另一個executeQuery()使用相同的Statement對象st1嗎?

回答

15

是的,你可以。但是,使用PreparedStatement來避免SQL注入漏洞會更好。

0

每當您將某些內容分配給引用類型時,您將用新引用替換舊引用。

例如...

MyObject obj = new MyObject("foo"); 
obj = new MyObject("bar"); 

本來MyObject來的,現在無引用實例與一些屬性設置爲最終會被垃圾收集「富」。

obj存儲對某個屬性設置爲「bar」的MyObject的引用。

+1

這不完全是他在做什麼。他問他是否可以重用* same *實例,而不僅僅是相同的參考 – n4rzul 2011-11-15 19:29:58

2

使用預準備語句的原始目的是爲了避免數據庫解析並重新編譯語句,所以它應該更快。

我沒有考慮SQL注入漏洞的使用,但我不確定是什麼,如果有任何數據檢查完成。我懷疑它是依賴於驅動程序的,因爲驅動程序的實現可以自由地將語句粘合在一起。如果有人有進一步的細節,請張貼。

+0

看起來JDBC規範不需要正確處理特殊字符。我想聽聽任何不能避免的驅動程序。 – 2008-12-23 20:13:48

+0

Steve,這個想法是:SQL注入是使用參數化語句避免了風險。請參閱http://en.wikipedia.org/wiki/SQL_injection#Preventing_SQL_Injection。當然你是對的,他們最初的目的是爲了避免不必要的解析。 – 2008-12-23 21:07:32

19

我遇到我在的Javadoc

尋找默認情況下,反應過來,只爲每個Statement對象ResultSet對象可以在同一時間打開。因此,如果一個ResultSet對象的讀取與另一個ResultSet對象的讀取交錯,則每個對象必須由不同的Statement對象生成。

1

我不確定結果集是否只有關閉纔會被垃圾收集。我認爲在編寫連接池時我有一個很酷的內存泄漏,所以相同的語句/連接重新使用了一百萬次。保持關閉我的JVM。我想這也可能是實現特定的,因爲封閉結果集的garabage集合可能不會被測試。