Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
gibt es mit dem Spring JDBC Template, oder auch anderen DB-Technologien., eine Möglichkeit ein Art "Batch Select" auszuführen?
Ich habe eine Liste von Objekten, mit deren Hilfe ich die Rückgabemenge auf eine Tabelle filtere.
Momentan iteriere ich über die Objekte und führe für jedes ein eigenes Select aus. Das dauert jedoch eine ganze weile. Da stellt sich mir die Frage, ob das nicht eleganter geht.
Momentan sieht es so aus:
PseudoCode:
for (MyObject object : myObjects)
Select * from TABELLE where Spalte1 = object.property1 and Spalte2 = object.property2;
Ich nutze das SimpleJdbcTemplate und eine Hashmap für die Parameter.
Mit dem IN Operator von SQL könnte es gehen
- über myObjects in Java iterieren und die Werte von property1 und property2 jeweils in einem eigenen Set merken
- Select * from TABELLE where Spalte1 IN (property1Set) and Spalte2 IN (property2Set) <-- Das ist Pseudocode. Du kannst natürlich nicht die Sets direkt als Parameter nehmen, sondern musst aus den gemerkten Sets den Parameterstring builden.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
class MyObject {
private int property1;
private int property2;
public MyObject(int property1, int property2) {
super();
this.property1 = property1;
this.property2 = property2;
}
public int getProperty1() {
return property1;
}
public int getProperty2() {
return property2;
}
}
List<MyObject> myObjects = new ArrayList<MyObject>();
myObjects.add(new MyObject(1, 2));
myObjects.add(new MyObject(3, 4));
myObjects.add(new MyObject(6, 5));
String str = new String("");
StringBuffer sb = new StringBuffer();
for (MyObject object : myObjects) {
sb.append("(");
sb.append(object.getProperty1());
sb.append(",");
sb.append(object.getProperty2());
sb.append(")");
sb.append(",");
}
sb.deleteCharAt(sb.length() - 1);
str = sb.toString();
System.out.println("SELECT * FROM tabelle WHERE (spalte1,spalte2) IN (" + str + ")");
}
}
Wenn du dein myObjects vorher nur einzig und allein für diesen Query aufbaust, könnte man den Code welcher zu myObjects führt auch noch mit in den Query verlagern und ein "SELECT * FROM tabelle WHERE EXISTS (SELECT 1 FROM myObjects-Tabelle WHERE myObjects-Bedingung)" ausführen. Das ist dann je nach RDBMS nochmal schneller bis wesentlich schneller.
Wie die IN-Bedingung zusammengebaut wird... vielleicht gibts da auch noch bessere Wege. Man sollte auch noch prüfen ob myObjects überhaupt was enthällt - ansonsten hagelt es Exceptions. Ggfl. gibt es je nach RDBMS auch Limitierungen wieviele Parametersets in einer IN-Clause mitgegeben werden dürfen. Ggfl. gibt es auch RDBMS welche combined-INs gar nicht können... Oracle und MySQL können es jedenfalls.
Achtung: Einzelne IN wie von nillehammer ergeben mitunter andere Ergebnisse.
Also z.B.
property1: 1
property2: 2
und
property1: 2
property2: 3
würde mit nillehammers Ansatz auch Zeilen liefern welche property1=1 und property2=3 haben.
[WR]Habe den Rest von OlliL's Post zwar nicht nachvollzogen, aber in dem Punkt hat er Recht. Wenn es auf die genaue Paarung von property1 und property2 ankommt, ist mein Ansatz keine Lösung![/WR]
Man könnte allerdings die einzelnen Bedingungspaare mit OR verknüpfen.
Ich habe es jetzt so gelöst, dass ich die Filterung applikationsseitig vornehme. Der Grund ist, dass es auf die exakte Paarung der Properties ankommt. Da diese sehr viele sein können, wäre es keine Option diese in das Statement zu packen und mit OR zu verknüpfen.