Prepared Statements - Where Anteil generieren.

Danielku15

Erfahrenes Mitglied
Hallo Leute.
Folgendes Problem: Ich hab eine Liste von Filterkriterien in einer Map (Key: Spaltenname Value: Suchstring).

Code:
+-------------------+-------------------+
| Key               | Value             |
+-------------------+-------------------+
| Spalte1           | Wert01            |
| Spalte2           | Wert* Value*      |
+-------------------+-------------------+

Diese Werte sollen nun in sicher in den Where Anteil meines PreparedStatements.
(SELECT * FROM Table WHERE ?)

Ziel ist es, den Value Part zuerst zu parsen und dann entsprechend ein SQL zu generieren:

Spalte1 beinhaltet kein Wildcard, dadurch direktes übereinstimmen:
Spalte1 = 'Wert01'
Spalte2 beinhaltet ein Wildcard und mehrere Werte. Bei Mehreren Werten will ich den String splitten und dann verarbeiten.
(Spalte2 LIKE 'Wert%' OR Spalte2 LIKE 'Value%'
)

Die beiden Kriterien müssen nun über AND verknüpft in den Whereanteil:

SELECT * FROM Table WHERE Spalte1 = 'Wert01' AND (Spalte2 LIKE 'Wert%' OR Spalte2 LIKE 'Value%'

Das ganze Simpel als String zu parsen wäre ja kein Problem, aber aufgrund der Zeiten von SQL Injections sollte das ganze in ein PreparedStatement rein.

Irgendwelche Ideen? Soll ich zuerst ein PreparedStatement Template generieren und dann alle Parameter als Array/Collection anhängen? Oder gibts da generell eine andere Möglichkeit?

Gruß Daniel
 
Hi

Sowas geht meines Wissens nicht mit einem PreparedStatement. Bei einem PreparedStatement kannst du immer genau ein Value setzen, nicht aber die Abfrage abändern.

Ich würde den String selbst zusammensetzen und dann mit Statement.executeQuery() ausführen.
 
Hi

Sowas geht meines Wissens nicht mit einem PreparedStatement. Bei einem PreparedStatement kannst du immer genau ein Value setzen, nicht aber die Abfrage abändern.

Ich würde den String selbst zusammensetzen und dann mit Statement.executeQuery() ausführen.

Da kann ich dir zum Glück für den TE nicht zustimmen.

Du kannst bei einem PreparedStatement mehrere Werte angeben (siehe API).

Für deinen Fall:
Du musst zuerst den String mit dem du das PreparedStatement erzeugst zusammenbauen. (Schleife über die Map Felder)
Und danach mit einer Schleife die Werte zum PreparedStatement setzen.

P.S.: Benutze StringBuilder für bessere Performance.
 
So ein Statement zusammenzubauen ist in der Tat recht simpel. Wenn du das Statement aber jedes Mal neu generierst, führst du damit aber die Idee des PreparedStatement quasi ad absurdum, da es darauf ausgerichtet ist, ein Statement(objekt) mehrfach wieder zu verwenden. Eine Idee könnte hier sein, sich die Spaltennamen als Schlüssel zu merken und einen dafür erzeugten Query zu merken und den bei einem weiteren Aufruf wiederzuverwenden. Wenn du die Queryerzeugung z.B. hinter einem Interface versteckst, könnte man sowas prima per AOP cachen.

Gruß
Ollie
 
Hallo Leute.
Ich habs nun so gemacht dass ich einfach für jeden gesetzten Suchbegriff ein ? = ? (bzw. den passenden "Template"-Code) an den SQL String anhänge. Die Spalte und den aufbereiteten Wert speicher ich dann in eine List und hänge die Werte mittels einer Schleife an das PreparedStatement an.

@ Oliver: Klar ist diese Variante gegen die Idee des PreparedStatements. Jedoch ist erstens PreparedStatement bereits von einer Library vorgegeben und zweitens sofern die üblichste Methode SQL-Injection vorzubeugen.

Mein Ziel ist folgendes: Ich habe ein Basis-Interface welches eine Methode bereits stellt an welches ich meine Map von Filterkriterien angeben kann. (public PreparedStatement getStatementByFilterCriterion(Map<String,String> msFilterCriterion) ) Es gibt eben eine Reihe von Suchmasken mit unterschiedlichen Filterkriterien. Und die konkreten Implementationen dieses Interfaces verarbeiten entsprechend die Filterkriterien.

Danke für eure Hilfe.
Daniel
 
Zurück