大多數SQL數據庫支持IN (list)
表達。這大致相當於提供一個或表達:
SELECT id FROM table WHERE food IN ('Apple', 'Banana') AND exp < ?
類似於
SELECT id FROM table WHERE (food = 'Apple' or food = 'Banana') AND exp < ?
在這兩種情況下,一些能夠RDBMS優化它。
但首先,您可以在IN中指定的列表項數量或可在語句中使用的字符數量受到限制。所以如果你的列表可以變長,你需要準備好運行多個語句。
其次,你不能*設置一個數組作爲PreparedStatement
的參數,並期望它與IN協同工作。
不幸的是,在普通的JDBC中,你只能連接一個字符串。這是令人不悅的,但沒有好的選擇(除非你想做一些事情,比如把食物列表作爲單個列表並使用「instring」表達式)。
確保添加儘可能多的?
(但是不要太多),爲您期望的參數,然後將它們設置在IN
:
String[] foods = ...;
int remain = foods.length;
int start = 0;
while(remain > 0)
{ if (remain >= 100)
executeBatch(foods, start, 100); start+=100; remain-=100;
else if (remain >= 30)
executeBatch(foods, start, 30); start+=30; remain-=30;
else {
executeBatch(foods, start, 1); start+=1; remain-=1;
}
}
void executeBatch(String[] f, int off, int len)
{
StringBuilder sqlBuf = StringBuilder("... IN(");
for(int i=0;i<len;i++) {
sqlBuf.append((i!=0)?",?":"?");
}
String sql = sqlBuf.append(") AND exp < ?").toString();
PreparedStatement ps = c.prepareStatement(sql);
for(int i=0;i<foods.length;i++)
ps.setString(i+1, foods[i+off]);
ps.setTimestamp(foods.length+1, now);
....
}
這避免了產生了很多不同的SQL語句進行編譯。 (只有100,30或1?))。您可以對OR情況使用相同的邏輯。
*不要與ARRAY數據庫類型混淆。
你是否需要單獨的每個結果?如果沒有,爲什麼不使用** select blah blah where food IN(「+ list +」)and expiration>?** – Alp
我試圖抓住所有沒有過期的食物@eckes –
@alp我其實沒有需要他們單獨和我會考慮使用'中' 編輯:肖恩明亮向我展示瞭如何在這種情況下使用'in' –