Hallo,
die folgende Anmerkung werde ich auch im Wiki zur Verfügung stellen.
Das Query-Interface besitzt folgende Methoden:
- . where
- . and
- . exist
- . orderBy
Jede dieser Methoden gibt das Query-Objekt selbst zurück, was ein „Stapeln“ von Bedingungen ermöglicht.
Die Methoden where() und and() erhalten als Parameter sogenannte SearchExpression, wie etwa: Rechnung.Auftragsnr.notNull().
Eine SearchExpression bietet die Möglichkeit, Felder miteinander oder Felder mit konkreten Werten zu vergleichen. Damit der Programmierer nicht immer mit dem komplexen Ausdruck new SearchExpression(…) arbeiten muss (dient auch nicht der Übersichtlichkeit), werden alle Felder innerhalb von BOs (z.b. Auftragsnr in Rechnung) mit Vergleichsoperatoren versehen (z.b. isNull(), notNull(), gte()), die zu diesem Datentyp passen und als Rückgabewert eine komplette SearchExpression zur Verfügung stellen: qryRechnung.where(Rechnung.Auftragsnr.notNull())
Je nach Feldtyp werden unterschiedliche Vergleichsoperatoren angeboten. Das Feld „Auftragsnr“ ist als Key eine Zahl und kann numerische Vergleiche vornehmen. Das Feld „Bemerkung“ bietet als reiner String-Wert dagegen keine Vergleiche wie gte() oder lte() an.
Gemeinsam haben alle Felder folgende Vergleiche:
- . eq
- . neq
- . isNull
- . notNull
Wichtig hier: Da es sich bei Querys wie auch bei SearchExpressions um Java-Klassen handelt, werden sie immer die equals()-Methoden besitzen. Diese Methode wird in Java für Vergleiche auf Objektebene verwendet, aber bei Querys innerhalb von Nuclos ignoriert.
Etwas komplizierter wird es nun beim „Stapeln“ von Suchbedingungen. Da gibt es zwei Möglichkeiten.
1. Verknüpfung mittels Query-Object.
Wie oben beschrieben, kann das Query-Objekt nebst where() und orderBy() mit Hilfe der and()-Methode mehrere SearchExpressions aufnehmen und miteinander verknüpfen. Die Methode or() gibt es an dieser Stelle nicht.
2. Verknüpfung mittels SearchExpression.
Die SearchExpression bietet außer den Vergleichsmöglichkeiten (Feld-Feld, Feld-Wert) auch die Möglichkeit eine andere SearchExpression „in sich aufzunehmen“. Die Methoden innerhalb der SearchExpression lauten dazu:
public SearchExpression and(SearchExpression pParentSearchExpression) {}
bzw.
public SearchExpression or(SearchExpression pParentSearchExpression) {}
Damit könnte folgendes Gebilde programmiert werden:
Query qryRechnung = QueryProvider.create(Rechnung.class);
Calendar today = Calendar.getInstance();
Calendar yesterday = Calendar.getInstance();
yesterday.add(Calendar.DAY_OF_WEEK, -1);
qryRechnung.where(Rechnung.Rechnungsdatum.eq(today.getTime()).or(
Rechnung.Rechnungsdatum.eq(yesterday.getTime())))
.and(Rechnung.Auftragsnr.notNull())
.and(Rechnung.Rechnungsnr.notNull())
.and(Rechnung.Waehrung.eq("EUR").or(
Rechnung.Waehrung.eq("USD"))
.orderBy(Rechnung.Rechnungsnr, true);
List results = QueryProvider.execute(qryRechnung);
Gerade diese zweite Variante ermöglicht mit der or()-Methode das Verschachteln von Abfragen. or() wie auch and() geben als Methoden der SearchExpression immer selbige zurück, weshalb sie miteinander verknüpft und als „Block“ der Query übergeben werden können.