Backend-Framework Entwicklung. Wir sind immer noch dabei. Unser Persistenz-Framework nimmt immer mehr Gestalt an und wir haben schon so viel dabei gelernt. Wir lieben die Möglichkeit typesafe auf unsere Entitäten zuzugreifen, was in ABAP nicht denkbar war. Diese Woche haben wir die Möglichkeit unserer Where-Conditions fertiggestellt. D.h. wir können typesafe Bedingungen im Code formulieren und das Ergebnis von irgendeiner Persistenz (derzeit MySQL) anfordern. Vor Kurzem gab es für das Absetzen von Conditions noch mehrere Möglichkeit. Uns war es zu wüst und letztendlich gibt es nur noch eine.
In sämtlichen Fällen gibt es eine Funktion „where“, die eine Condition zurückliefert. Hier gibt es 3 Möglichkeiten:
1. die einfache Bedingung. Über die Attribute des DataObjects können die Operatoren eq, gt, ge, lt, le, not, like aufgerufen und der Vergleichswert übergeben werden.
val trees = Tree.find { where { type eq TreeType.LEAF } } val trees = Tree.find { where { name like "%in%" } }
2. die kombinierte Bedingung. In diesem Fall eine einfache OR Verknüpfung. Bedingungen können durch das Aneinanderreihen oder durch Verwendung von varargs geschachtelt werden. Der zweite Fall wird benötigt, um Bedingungen durch Klammern von einander zu trennen.
Tree.find { where { (type eq TreeType.LEAF).or(type eq TreeType.NEEDLE) } } Tree.find { where { or(type eq TreeType.LEAF, type eq TreeType.NEEDLE) } }
3. die literal Bedingung. Der Verwender kann jede Art von Request absetzen. Platzhalter werden durch Bindings ersetzt. Diese Variante ist nicht typesafe, sondern dient für Requests, die derzeit nicht durch das Framework unterstützt werden.
Tree.find { where { literal("type IN ?") .bindList(listOf(TreeType.LEAF, TreeType.PALM)) } }
Außerdem haben wir die zwei Operatoren „is null“ und „is not null“ eingeführt. So können null-Werte aus der Datenbank gelesen werden.
Tree.count { where { changedAt.isNull() } }
Unsere max und min Funktionen haben wir ebenfalls erweitert. Sie liefern nun auch ein Element vom selektierten Feldtyp zurück. Bspw. liefert max( createdAt) nun einen Timestamp. Auch sie verwenden nun standardisiert das Conditions-Konzept, um das Ergebnis einzuschränken.
Tree.max { createdAt }.nanos Tree.max({ createdAt }) { where { type eq TreeType.LEAF } }
Des Weiteren haben wir an unserem DataObjectCache gearbeitet. Er verhindert, dass Instanzen des selben Schlüssels mehrfach geladen werden. Wird der Cache verwendet und an unterschiedlichen Stellen auf dasselbe Objekt zugegriffen und verändert, greifen alle Verwender konsistent auf das selbe Objekt zu.
Weiterhin wurde der dbQueryExecutor um eine Logger-Funktion erweitert. Bei Verwendung des Loggers wird jeder ausgeführte Query auf der Konsole ausgegeben.