2015-03-30 79 views
1

我需要創建一個字段更新爲一個id列表。這個列表的大小是可變的。批量更新與IN(x,x,x)

什麼我不知道是,接下來的兩個可能的選項是什麼好:

選項1:批量更新:

PreparedStatement update = connection.prepareStatement(" UPDATE table set field = value where id = ?"); 
for (id : ids){ 
    update.setInt(id); 
    update.addBatch(); 
} 
update.executeBatch(); 

選項2:IN(X,X,X)

PreparedStatement list_update = connection.prepareStatement("UPDATE table set field = value where id in (" + comma_separated_ids(ids) + ")"); 

private String comma_separated_ids(int[] ids){ 
    // receives [1,2,3] and returns "1,2,3" 
} 

我更傾向於第二,但我不喜歡where id in (" + comma_separated_ids(ids) + ")");因爲可能的SQL注入。

那麼,有什麼選擇更好?數字1或數字2.如果數字2是這種情況,我如何避免SQL注入?

回答

0

選項1是相當更優雅,但選項2(如果參數的數量在某些時候變成大甚至更多),你會有更好的表現。只需添加?所需的參數IN ...然後再次循環並設置它們。不要將值原樣設置爲IN子句中,請使用參數化的時尚(與?一樣)。

即使有兩個循環會比(對於數據庫執行相同數量的查詢更快)。此外,雖然確實如果您使用的是PreparedStatement,您將一次執行批處理中的所有查詢,但數據庫服務器將執行與您構建的批處理語句數量一樣多的UPDATE查詢。另一點是交易,如果您決定全部或全部爲空,則由您自行決定,但無論如何這會增加更多時間。您始終可以衡量這兩種解決方案

注:我見過這裏StackOverflow的許多答案,他們指出,一些?沒有作品參數上IN條款......這不是真的,至少爲:DB2,Oracle和MySQL的使用JDBC 4.0。它確實有用。

+0

很好的答案。謝謝,Machina =)我現在沒有時間真正衡量表現,但我想我會在未來做到這一點 – 2015-03-31 06:04:36