Dynamische Liste von Oder Bedingungen

Gegeben sei eine Map parameters die alle Konditionen enthält die abgefragt werden sollen. In der Map ist der Key gleich dem Feldnamen in der Tabelle und der Value der Wert mit dem der Inhalt der Spalte verglichen werden soll.

Map<String, Object> params = ...;

Jetzt kann man die Oder Bedingung mit Jooq dynamisch zusammensetzen.

Condition result =
params
    .entrySet()
    .stream()
    .reduce(
        DSL.noCondition(),
        (condition, entry) -> condition.or(
            // Hier wird mit Hilfe Table.field() das Feld aus der Tabelle nach ihrem Namen gesucht.
            // Achtung: Nicht vorhandene Felder führen zu einer NullPointerException.
            ((Field<Object>) E.field(entry.getKey())).eq(entry.getValue())
        ),
        Condition::or
    );

Für alle Einträge in der Map (EntrySet) wird ein Stream erzeugt. Jeder Entry wird mit der Reduce Methode mit Condition::or verknüpft. Initialisiert wird die Reduce Operation mit DSL.noCondition(). Also wenn die Map leer ist, dann wird noCondition() zurückgegeben.

Dependency Management unter SpringBoot 2

Fügt man als Dependency spring-boot-starter-jooq ein, dann werden alle Abhängigeiten sowie Jooq als Abhängigkeiten eingefügt. Soweit so gut. Aber was ist, wenn man eine neuere Version von Jooq (zum Beispiel aufgrund eines Bugs) verwenden möchte?

Override Version

Unter Gradle kann man mit ext [jooq.version] die zu verwendende Version vorgeben.

// Override supported Jooq version 3.11.9
ext['jooq.version'] = '3.11.11'

Nun wird die aktuelle Version von Jooq 3.11.11 verwendet.

Die Ausgabe des Logos von Jooq verhindern

Beim Starten eines Queries wird normalerweise das Logo von Jooq ausgegeben. Das ist auch nicht weiter schlimm, es ist nur beim Debuggen der Anwendung manchmal ein wenig störend, weil es viel Platz auf der Konsole einnimmt.

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@  @@        @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@
@@@@@@@@@@@@@@@@  @@  @@    @@@@@@@@@@
@@@@@@@@@@  @@@@  @@  @@    @@@@@@@@@@
@@@@@@@@@@        @@        @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@        @@        @@@@@@@@@@
@@@@@@@@@@    @@  @@  @@@@  @@@@@@@@@@
@@@@@@@@@@    @@  @@  @@@@  @@@@@@@@@@
@@@@@@@@@@        @@  @  @  @@@@@@@@@@
@@@@@@@@@@        @@        @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  Thank you for using jOOQ 3.11.9

Dank geht an dieser Stelle an Lukas Eder für dieses tolle Werkzeug.

Wie kann nun das Logo abgeschaltet werden? Dazu muss nur die Property org.jooq.no-logo auf true gesetzt werden. Ich löse das in dem ich eine Klasse JooqConfig mit einem Bean erstelle. Die Komponente wird so beim Component Scan gefunden und die Property gesetzt, sodass beim Starten kein Logo angezeigt wird.

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class JooqConfig {
    @Bean
    private void disableLogo() {
        System.setProperty("org.jooq.no-logo", "true");
    }
}

Credentials auslagern

Neben der Möglichkeit die Credentials mit dem Gradle Plugin Credentials zu verwalten, kann man auch zum Beispiel dieses in eine weitere Datei auszulagern. Hierfür bietet sich YAML an.

Hier die jooq.yaml

---
jdbc:
  password: secret
  username: usr

In dem Buildscript jooq.gradle lesen wir die Daten aus dem YAML ein. Das SnakeYaml nutze ich hierfür um die cfg zu definieren.

...
jooq {
  def cfg = new org.yaml.snakeyaml.Yaml().load(new File("" + rootProject.projectDir + "/jooq.yml").newInputStream())
...

Weiter unten im Abschnitt xxx können jetzt die Credentials aus dem jooq.yaml angegeben werden…

...
    jdbc {
      driver = 'org.mariadb.jdbc.Driver'
      url = 'jdbc:mariadb://server:3306/database'
      username = cfg.jdbc.username
      password = cfg.jdbc.password
    }
...

Jooq 3.11.7

Seit meinen letztem Beitrag über das Release von Jooq 3.11.0 sind jede Menge Fehler behoben worden und auch ein paar neue Features hinzugekommen. Die wichtigsten Änderungen möchte ich hier in diesem Beitrag kurz zusammenfassen.

Mit der Version 3.11.7 ist es jetzt die 7. Aktualisierung des Java SQL DSL Framework seit der Veröffentlichung von 3.11.0.

Neue Features in 3.11.2

  • Keine alten XSDs mehr Mit dem Release 3.11.2 werden keine alten XSD Dateien mehr in den Binary’s ausgeliefert.

  • Disable ORDER BY in emulierten OFFSET … FETCH Paginierung Klauseln In Datenbanken die OFFSET … FETCH nicht unterstützen, wird seit Jahren das Verhalten emuliert. Da Datenbanken aus einer Window Funktion die Sortierung nicht garantieren, wird diese im äußeren Query durchgeführt. Die Erfahrung hat gezeigt, dass das oft nicht nötig ist. Als kleiner Performance Tweak kann daher die Sortierung jetzt abgeschaltet werden.

  • Anzahl der Rows wird im LoggerListener wieder ausgegeben Mit dem Commit wurde das Verhalten geändert. Das ursprünglich Verhalten wurde wiederhergestellt und die Anzahl der Rows geloggt.

Neue Features in 3.11.5

  • Der Parser liest nun CREATE INDEX .. ON .. USING btree

Neue Feature in 3.11.6

Bugfixes seit 3.11.0

Seit dem Release sind mehr als 70 Fehler behoben worden. Eine vollständige Liste der Änderungen gibt es in den Release Notes.

Am 07.07.2018 wurde mit 3.11.0 die letzte Version von Jooq freigegeben.

Neues in Version 3.11.0

Neu in der Version 3.11.0 sind die implizieten Joins die man aus ORM Frameworks wie Hibernate, Doctrine oder anderen her kennt.

Beispiel für implizietes joinen

Gegeben seinen 2 Tabellen Buch und Author die über den Join miteinander verknüpft werden.

SELECT author.vorname, author.nachname, buch.titel
FROM buch
JOIN author ON buch.author_id = author.id

Das Framework Hibernate ist in der Lage dieses im internen Graphen zu erkennen und automatisch (impliziet) zu joinen und daher ist folgendes Query valide:

SELECT buch.author.vorname, buch.author.nachname, buch.titel FROM buch

In der neuen Version 3.11.0 wird im Codegenerator Code erzeugt, der die Berechnung des Graphen on the fly übernimmt und den Join hinzufügt. Somit ist folgender Code nun möglich:

ctx.select(BUCH.author().VORNAME, BUCH.author().NACHNAME, BUCH.TITEL)
   .from(BUCH)
   .fetch();

Dies kann auf beliebige Queries mit beliebiger Verschachtelungstiefe erfolgen.

Siehe auch type-safe-implicit-join-through-path-navigation-in-jooq-3-11.

Window Funktionen unter MariaDB 10.2 werden unterstützt

Mit dem Schließen des Tickets 7514 werden die Window Funktionen in MariaDB unterstützt.

Parser

Der Parser der SQL Statements parsen und in einen AST überführen kann wurde weiter verbessert. Eine Demo zum übersetzen von verschiedenen SQL-Dialekten steht unter translate zur Verfügung. Es wurden viele neue Klauseln und Funktionen verschiedener Hersteller in (DDL, DML) hinzugefügt.

Java 10 Support

Java 10 wird erstmals mit Integrationstest abgedeckt. Um eindeutige Paketnamen in den verschiedenen Modulen zu gewähren, wurde der Code entsprechend refaktorisiert.

Fehlerkorrekturen

Natürlich sind auch jede Menge weiterer Fehler in der Version behoben worden. Alle Fehler und weiteren Features sind auf der Notes Seite zu finden.

Scala wird aus OSS Version entfernt

Der Support für Scala wird ab Version 3.11.0 aus der OSS Version entfernt. Scala kann nur noch mit der Pro oder Enterprise Version verwendet werden.

Java 9 Module Support für Jool

Jool ist ein Baustein auf dem Jooq aufbaut. Mit der Modularisierung seit Java 9 müssen noch etliche Java Frameworks an das neue Modulsystem angepasst werden. Mit der Version 0.9.13 wird Jool in 2 Versionen ausgeliefert. Die alte für Java 8 hat ein Suffix -java-8 bekommen.

  • Java 8: ArtifactId jool-java-8
  • Java 9: ArtifactId jool

Ab Jooq 3.9.0 wurde ein Parser für SQL Statements hinzugefügt. Der Parser soll einem PublicReview unterzogen werden und ist daher noch als experimental gekenntzeichnet.

Mit dem Parser wird es möglich sein einen SQL Ausdruck als String in einen Jooq-Ausdrucksbaum zu verwandeln. Somit sollte auch eine Art universeller Übersetzung von einem SQL-Dialekt in einen anderen möglich sein.

  • Added support to map java.time.LocalDate to JDBC DATE.
  • Added support to map java.time.LocalTime to JDBC TIME
  • Added support to map java.time.LocalDateTime to JDBC TIMESTAMP.
  • Added support to map java.time.OffsetTime to JDBC TIME_WITH_TIMEZONE.
  • Added support to map java.time.OffsetDateTime to JDBC TIMESTAMP_WITH_TIMEZONE.

Datenbank Code muss neu generiert werden. Für den Generator gibt es dafür folgenden Switch:

<javaTimeTypes>true</javaTimeTypes>

Eine paralelle Generierung ist nicht möglich, d.h. die alten SQL Datum/Zeit Typen stehen dann nicht zur Verfügung.

.where(ACCOUNTS.LAST_UPDATE.le(Timestamp.valueOf(LocalDateTime.now().minusDays(7L))))

wird zu

.where(ACCOUNTS.LAST_UPDATE.le(LocalDateTime.now().minusDays(7L)))

much better. Thank you Lukas !!!

Lukas Eder hat alle Jooq Fans ein tolles Weihnachtsgeschenk gemacht. Pünktlich zum Fest ist die neue Version 3.9.0 erschienen. Auch diesmal sind wieder jede Menge neue Features vorhanden.

  • Experimental Parser
  • Checker framework integration
  • JSR-310 Unterstützung
  • Einfachere Transaktions API
  • Im- und Export der Informations Schema
  • Und viele weitere Verbesserungen

 

Am 22.04.2015 wurde die neue Version von Jooq 3.6.0 veröffentlicht. In der aktuellen Version wurden nicht nur um die 100 Fehler beseitigt, es wurden auch genauso viele neue Features aus der Community mit in das Release aufgenommen. Auch das Handbuch wurde korrigiert und mit zahlreichen neuen Beispielen versehen.