[JAVA] Erste Schritte mit Doma-using Logical Operators wie AND und OR in der WHERE-Klausel der Criteria-API

Einführung

Wenn Sie die WHERE-Klausel von SQL erstellen, um mehrere Bedingungen anzugeben, müssen Sie mit logischen Operatoren wie AND und OR verketten. Dieser Artikel zeigt, wie eine solche Verkettung logischer Operatoren durch die Kriterien-API in Doma 2.43.0 dargestellt werden kann.

Die Verkettung logischer Operatoren ist eine einfache Funktion, die in SQL ausgedrückt werden kann. Die Realisierung als Programmiersprache ist jedoch eine zu berücksichtigende Frage. Das Merkmal von Doma ist, dass es unter Verwendung eines Lambda-Ausdrucks ausgedrückt werden kann.

Eine Übersicht über Doma und die Kriterien-API finden Sie in den anderen Artikeln unter Einführung in Doma.

In diesem Artikel verwendeter Beispielcode

Die Datenbank enthält nur eine Mitarbeitertabelle, die Mitarbeiter darstellt.

schema.sql


create table employee (
    id integer not null primary key,
    name varchar(255) not null,
    age integer not null, 
    version integer not null);

Bereiten Sie die Employee-Klasse als Entitätsklasse vor, die der Employee-Tabelle entspricht.

Employee.java


@Entity(metamodel = @Metamodel)
public class Employee {
  @Id
  public Integer id;
  public String name;
  public Integer age;
  @Version public Integer version;
}

Wir werden ein "EmployeeRepository" vorbereiten und die "select" -Methode dieser Klasse neu schreiben, um einige Beispiele zu zeigen.

public class EmployeeRepository {

  private final Entityql entityql;

  public EmployeeRepository(Config config) {
    this.entityql = new Entityql(config);
  }

  public List<Employee> select() {
    //Hier ist ein Codebeispiel, das auf verschiedene Arten umgeschrieben wurde
  }
}

Impliziter UND logischer Operator

Wenn die Suchbedingungen (eq (..., ...) in diesem Beispiel) angeordnet sind, werden sie implizit durch AND verkettet.

    Employee_ e = new Employee_();
    return entityql.from(e).where(c -> {
      c.eq(e.id, 1);
      c.eq(e.name, "aaa");
      c.eq(e.age, 20);
    }).fetch();

Das generierte SQL sieht folgendermaßen aus: (Im Folgenden wird die SQL mit dem eingebetteten gebundenen Wert angezeigt. In Wirklichkeit wird die SQL jedoch mit der Bindungsvariablen "?" Ausgegeben.)

select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.id = 1 and t0_.name = 'aaa' and t0_.age = 20

Expliziter UND logischer Operator

Im vorherigen Beispiel wurde die Methode, die AND entspricht, nicht aufgerufen, aber es ist auch möglich, die Methode "und", die AND entspricht, wie folgt explizit aufzurufen. Die Methode and empfängt einen Lambda-Ausdruck.

    Employee_ e = new Employee_();
    return entityql.from(e).where(c -> {
      c.eq(e.id, 1);
      c.and(() -> c.eq(e.name, "aaa"));
      c.and(() -> c.eq(e.age, 20));
    }).fetch();

Das generierte SQL lautet wie folgt und es wird dasselbe SQL wie im vorherigen Beispiel generiert (es gibt jedoch Unterschiede wie das Vorhandensein oder Fehlen von Klammern).

select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.id = 1 and (t0_.name = 'aaa') and (t0_.age = 20)

ODER logischer Operator

Um durch ODER zu verketten, rufen Sie die Methode oder wie folgt auf: Die Methode or empfängt einen Lambda-Ausdruck.

    Employee_ e = new Employee_();
    return entityql.from(e).where(c -> {
      c.eq(e.id, 1);
      c.or(() -> {
        c.eq(e.name, "aaa");
        c.eq(e.age, 20);
      });
    }).fetch();

Das generierte SQL sieht folgendermaßen aus:

select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.id = 1 or (t0_.name = 'aaa' and t0_.age = 20)

Automatische Entfernungsfunktion für führendes UND und ODER

Ähnlich wie im vorherigen Beispiel, aber welche Art von SQL generiert der folgende Code?

    Employee_ e = new Employee_();
    return entityql.from(e).where(c -> {
      c.or(() -> {
        c.eq(e.name, "aaa");
        c.eq(e.age, 20);
      });
      c.eq(e.id, 1);
    }).fetch();

Sie könnten denken, dass ein zusätzliches ODER unmittelbar nach der WHERE-Klausel generiert wird, aber Doma entfernt automatisch das UND und das ODER am Anfang der WHERE-Klausel, sodass die folgende SQL generiert wird.

select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where (t0_.name = 'aaa' and t0_.age = 20) and t0_.id = 1

Diese Funktion ist nützlich, wenn die Notwendigkeit von UND oder ODER aufgrund einer bedingten Verzweigung in der WHERE-Klausel nicht statisch bestimmt wird.

    Employee_ e = new Employee_();
    return entityql.from(e).where(c -> {
      if (Ein Zustand) {
        c.or(() -> {
          c.eq(e.name, "aaa");
          c.eq(e.age, 20);
        });
      }
      if (Einige Bedingung 2) {
        c.or(() -> {
          c.eq(e.name, "bbb");
          c.eq(e.age, 30);
        });
      }
    }).fetch();

Verschachtelung UND und ODER

Sie können beliebig viele "und" und "oder" ohne Einschränkungen verschachteln.

    Employee_ e = new Employee_();
    return entityql.from(e).where(c -> {
      c.eq(e.id, 1);
      c.or(() -> {
        c.eq(e.name, "aaa");
        c.eq(e.age, 20);
        c.or(() -> {
          c.eq(e.name, "bbb");
          c.eq(e.age, 30);
        });
      });
    }).fetch();

Der obige Code generiert das folgende SQL:

select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.id = 1 or (t0_.name = 'aaa' and t0_.age = 20 or (t0_.name = 'bbb' and t0_.age = 30))

abschließend

Ich habe gezeigt, wie die Verkettung logischer Operatoren in der Doma Criteria API ausgedrückt werden kann.

Wie eingangs erwähnt, drückt die Criteira-API von Doma die Verkettung logischer Operatoren als Lambda-Ausdruck aus. Es gibt eine Methodenkette als eine andere Ausdrucksmethode, aber ich persönlich denke, dass die Methodenkette eine Schwäche hat. Es ist anfällig für bedingte Verzweigungen. Wenn es einen bedingten Zweig gibt, bricht die Kette und die Komplexität nimmt sofort zu. Dies liegt daran, dass Sie das zu verkettende Objekt in einer Variablen speichern müssen, um die Kette zu verbinden. Andererseits ist die Methode, die einen Lambda-Ausdruck wie die Criteria-API von Doma verwendet, einfach und gut lesbar, da es keinen Unterschied im Schreibstil gibt, je nachdem, ob eine bedingte Verzweigung enthalten ist oder nicht (nur weil sie von if-Blöcken umgeben ist). Ich denke.

Recommended Posts

Erste Schritte mit Doma-using Logical Operators wie AND und OR in der WHERE-Klausel der Criteria-API
Erste Schritte mit Doma-Dynamic Erstellen von WHERE-Klauseln mit der Kriterien-API
Erste Schritte mit der Doma-Projektion mit der Criteira-API
Erste Schritte mit Doma-Using Joins mit der Criteira-API
Erste Schritte mit Doma-Einführung in die Kriterien-API
Erste Schritte mit Reactive Streams und der JDK 9 Flow API
[jOOQ] Wie in der WHERE / AND / OR-Klausel WANN FALLEN
Fassen Sie die wichtigsten Punkte für den Einstieg in JPA zusammen, die Sie mit Hibernate gelernt haben
Betrachten wir die Bedeutung von "Stream" und "Collect" in der Stream-API von Java.
[Firestore] Extrahieren Sie die Sammlung mit der where-Bedingung in Ruby und löschen Sie den Datensatz