| Auszug | ||
|---|---|---|
| ||
Nuclos QueryProvider: create, where, and, orderBy, execute, get, getByState, getByProcess, exist, SearchExpression, NuclosLogicalDeleted. |
Sprache: Deutsch · English
Typisierte Datenabfragen in Regeln – create/where/and/orderBy/execute, getByState, getByProcess, Subqueries.
| Status | ||||
|---|---|---|---|---|
|
| Status | ||||
|---|---|---|---|---|
|
| Status | ||||
|---|---|---|---|---|
|
| Status | ||||
|---|---|---|---|---|
|
| Panel | ||||
|---|---|---|---|---|
| ||||
Auf dieser Seite
|
...
|
Der QueryProvider
...
lädt Daten aus
...
Nuclos
...
und stellt sie als Businessobjekt oder Liste in Regeln bereit. Statt SQL wird eine typisierte, abstrakte Query-Sprache verwendet.
| Info | ||
|---|---|---|
| ||
Ohne |
...
werden logisch gelöschte Einträge nicht berücksichtigt |
...
. |
...
Nur |
...
|
...
liefert gelöschte Einträge |
...
. |
...
Alle Einträge, die nicht logisch gelöscht wurden:
...
...
Query<Auftrag> qAuftrag = QueryProvider.create(Auftrag.class);
qAuftrag.where(Auftrag.NuclosLogicalDeleted.eq(Boolean.FALSE))
// oder einfach nur
Query<Auftrag> qAuftrag = QueryProvider.create(Auftrag.class);Alle Einträge, die logisch gelöscht wurden:
| Codeblock |
|---|
Query<Auftrag> qAuftrag = QueryProvider.create(Auftrag.class);
qAuftrag.where(Auftrag.NuclosLogicalDeleted.eq(Boolean.TRUE)) |
Alle Einträge anzeigen:
Legt ein typisiertes Query-Objekt für ein Businessobjekt an.
| Codeblock | ||
|---|---|---|
|
| Codeblock |
|---|
Query<Auftrag> qAuftrag = QueryProvider.create(Auftrag.class);
qAuftrag.where(Auftrag.NuclosLogicalDeleted.eq(Boolean.TRUE).or(Auftrag.NuclosLogicalDeleted.eq(Boolean.FALSE))) |
...
Mit Hilfe dieser Methode kann ein typisiertes Query-Object angelegt werden, mit dessen Hilfe Datenbankabfragen ausgeführt werden können. Dabei wird auf eine abstrakte Query-Language zurückgegriffen, Abfragen mit SQL-Syntax sind nicht möglich. Die übergebene Klasse muss vom Typ BusinessObject sein. Das Query-Object als Rückgabewert ist ebenfalls typisiert und muss dem übergebenen BusinessObject entsprechen. Zum Ausführen der Query muss die unten beschriebene execute()-Methode verwendet werden.
...
public static <T extends BusinessObject> Query<T> create(Class<T> type) |
...
; |
...
...
Diese Methode führt eine typisierte Query auf der Datenbank aus. Da die Suchabfrage generell mehrere Ergebnisse zurückliefern kann, ist der Rückgabewert vom Typ List. Diese ist ebenfalls typisiert und bei keinem gefundenen Treffer leer, aber nicht null.
...
Führt die Query aus und liefert eine typisierte, nie null-Liste (leer bei keinem Treffer).
| Codeblock | ||
|---|---|---|
| ||
public static <T extends BusinessObject> List<T> execute(Query<T> |
...
|
...
query); |
...
...
Diese Methode ermöglicht die Suche nach einem konkreten Datenbankeintrag. Dazu muss der Typ und die Id angegeben werden. Wird kein Element gefunden, ist der Rückgabewert null.
| Codeblock |
|---|
public static <T extends BusinessObject> T get(Long id) {
return getService().get(id);
} |
Ein Beispiel finden Sie hier.
...
Diese Methode ermöglicht die Suche nach Datenbankeinträgen, die einer bestimmten Aktion zugeschrieben sind. Jede Aktion in Nuclos gehört zu einem Businessobjekt. Bei der Suche nach Einträgen muss deshalb das Businessobjekt nicht extra angegeben werden. Zwingend erforderlich dagegen ist die Angabe mindestens einer Aktion.
| Codeblock |
|---|
public static <PK, T extends Stateful & BusinessObject<PK>> List<T> getByProcess(Process<T> process, Process<T>... additionalProcesses) throws BusinessException; |
Ein Beispiel finden Sie hier.
...
Diese Methode ermöglicht die Suche nach Datenbankeinträgen, die einen bestimmten Status besitzen. Da ein Status immer einem Statusmodell angehört, das von mehreren Businessobjekten werden kann, ist die Angabe eine Businessobjekt notwendig. Weiterhin muss mindestens ein Status der Suche übergeben werden.
| Codeblock |
|---|
public static <PK, T extends Stateful & BusinessObject<PK>> List<T> getByState(Class<T> type, State state, State... additionalStates) throws BusinessException |
Ein Beispiel finden Sie hier.
Das Query-Interface besitzt folgende Methoden:
...
| Codeblock |
|---|
Query<T> and (Attribute element, Boolean ascending); |
Mit Hilfe dieser and() - Methode lässt sich eine Mehrfachsortierung bei Abfragen realisieren. Die Reihenfolge der Angaben innerhalb der Query ergibt die Reihenfolge der Sortierung bei der Abfrage.
| Codeblock |
|---|
Query<T> and (SearchExpression elm); |
Mit Hilfe dieser and() - Method lassen sich SearchExpressions miteinander verknüpfen. Der Rückgabewert ist die Query selbst, was eine Aneinanderreihung ermöglicht.
...
Mit der Exist() - Methode lassen sich Unterabfragen einbinden.
Allgemein kann eine Subquery erstellt und eingebunden werden, deren ID als Fremdschlüssel in der äußeren Query vorhanden ist und so mit dieser verknüpft werden kann.
| Codeblock |
|---|
<P extends BusinessObject> Query<T> exist(Query<P> subQuery, Attribute element); |
Weiterhin kann mit der Angabe des Vergleichsfeldes aus der Subquery angegeben werden, mit welchem Wert der Vergleich in der MainQuery stattfinden soll.
...
Liest einen konkreten Eintrag über Typ und Id; null, wenn nichts gefunden.
Suchen Einträge nach Status bzw. nach zugewiesener Aktion (Prozess). Mindestens ein Status/eine Aktion ist erforderlich.
Auf Feldern stehen passende Vergleichsoperatoren bereit: eq, neq, isNull, notNull (alle Typen) sowie Gt, Gte, Lt, Lte (numerisch). where()/and()/orderBy() geben die Query zurück und lassen sich stapeln. Ein or() existiert nur auf SearchExpression-Ebene, wodurch sich Blöcke verschachteln lassen.
| Codeblock | ||
|---|---|---|
| ||
boolean sortAscending = true; Query<Auftrag> queryAuftrag = QueryProvider.create(Auftrag.class); queryAuftrag.where(Auftrag.Auftragsnr.notNull()) .and(Auftrag.Bestellwert.Gt(BigDecimal.ZERO)) |
...
Die Subquery selbst muss nicht ausgeführt werden, sondern wird als Instanz der äußeren Query übergeben und dort ausgewertet.Sehen Sie dazu ein Beispiel: hier
...
| Codeblock |
|---|
Query<T> orderBy(Attribute element, Boolean ascending); |
Mit Hilfe der Order-Methode kann eine Sortierung vorgenommen werden. Als Parameter muss das Feld (nachdem sortiert werden soll) des Businessobjekts (auf das sich die Query bezieht) und eine Sortierreihenfolge angegeben werden.
...
| Codeblock |
|---|
Query<T> where (SearchExpression elm); |
Mit Hilfe der where() - Methode kann eine Suchbedingung für die Query angegeben werden. Mit der Methode and() können diese noch erweitert werden.
.orderBy(Auftrag.Auftragsnr, sortAscending); |
| Codeblock | ||
|---|---|---|
| ||
List<Auftrag> results = QueryProvider.execute(queryAuftrag);
for (Auftrag a :results) {
BigDecimal bestellwert = a.getBestellwert();
} |
Mit exist(subQuery, …) lassen sich Subqueries über (Fremd-)Schlüssel einbinden; die Subquery selbst wird nicht separat ausgeführt.
| Codeblock | ||
|---|---|---|
| ||
// Alle Kunden, fuer die Zahlungsbedingungen hinterlegt wurden
Query<Kunde> qryKunden |
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:
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:
| Codeblock |
|---|
public SearchExpression and(SearchExpression pParentSearchExpression) {}
public SearchExpression or(SearchExpression pParentSearchExpression) {} |
...
= QueryProvider.create( |
...
Kunde.class); |
...
qryKunden.where(Kunde.Zahlungsbedingung.notNull()); // Nun brauchen wir alle Bestellungen dieser Kunden Query<Bestellung> queryBestellungen = |
...
QueryProvider.create(Bestellung.class); queryBestellungen.where(Bestellung.Bestellnr.notNull()) |
...
.exist(qryKunden, Bestellung.KundeId) |
...
.orderBy( |
...
Bestellung. |
...
Bestellnr, true); |
...
List<Bestellung> results = QueryProvider.execute( |
...
queryBestellungen); |