[JAVA]

Diesmal war es übrigens "ob sich Linien (1 Dimension) überlappen", aber wenn die Anzahl der Dimensionen erhöht wird, "ob sich Ebenen (2 Dimensionen) überlappen" und "ob sich Volumenkörper (3 Dimensionen) überlappen". Sie können auf die gleiche Weise urteilen. Wenn Sie interessiert sind, probieren Sie es bitte aus. Java, Algorithmen, Programmierausbildung, Anfänger in der Programmierung von Doma-Primer-Unterabfragen mit Kriterien-API Einführung Doma Ausdrücken von SQL-Unterabfragen mit der Kriterien-API von 2.43.0 Zeigt an, ob dies möglich ist.

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

In diesem Artikel verwendeter Beispielcode

Hier ist ein vereinfachter Code. Im vollständigen Projekt finden Sie den vollständigen Beispielcode.

Die Datenbank verfügt über eine Abteilungstabelle, die Abteilungen darstellt, und eine Mitarbeitertabelle, die Mitarbeiter darstellt.

schema.sql


create table department (
    id integer not null primary key,
    name varchar(255) not null);

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

Bereiten Sie eine Abteilungsklasse vor, die der Abteilungstabelle entspricht, und eine Mitarbeiterklasse, die der Mitarbeitertabelle entspricht.

Department.java


@Entity(metamodel = @Metamodel)
public class Department {
  @Id Integer id;
  String name;
}

Employee.java


@Entity(metamodel = @Metamodel)
public class Employee {
  @Id Integer id;
  String name;
  @Column(name = "DEPARTMENT_ID")
  Integer departmentId;
}

Wir werden "EmployeeRepository" vorbereiten und dieser Klasse einige Methoden hinzufügen, um ein Beispiel zu zeigen.

public class EmployeeRepository {

  private final Entityql entityql;

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

Unterabfrage mit IN-Prädikat

Rufen Sie die In-Methode auf.

Beachten Sie, dass der an das "where" der Unterabfrage übergebene Lambda-Ausdruck anstelle der äußeren "c" -Instanz die vom Parameter übergebene "c2" -Instanz verwendet.

  public List<Employee> selectByDepartmentName_in(String departmentName) {
    Employee_ e = new Employee_();
    Department_ d = new Department_();
    return entityql
        .from(e)
        .where(
            c ->
                c.in(
                    e.departmentId,
                    c.from(d).where(c2 -> c2.eq(d.name, departmentName)).select(d.id)))
        .fetch();
  }

Wenn der Parameter "departmentName" "SALES" ist, sieht das generierte SQL 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_.DEPARTMENT_ID
from
    Employee t0_ 
where 
    t0_.DEPARTMENT_ID in (
        select 
            t1_.id
        from
            Department t1_
        where
            t1_.name = 'SALES'
    )

Wenn die Abteilungstabelle einen zusammengesetzten Schlüssel enthält, können Sie auch nach Schlüsselkombination suchen, indem Sie "Tuple2" wie folgt verwenden (das Format, in dem die zu verwendende Datenbank verwendet wird, gibt jedoch mehrere Spalten im IN-Prädikat an). Muss unterstützt werden).

    c.in(
        new Tuple2<>(e.departmentId1, e.departmentId2),
        c.from(d).where(c2 -> c2.eq(d.name, departmentName)).select(d.id1, d.id2)))

Die Methode "notIn", die dem Prädikat NOT IN entspricht, wird ebenfalls bereitgestellt.

Unterabfrage mit EXISTS-Prädikat

Rufen Sie die Methode "existiert" auf.

Die Vorsichtsmaßnahmen sind dieselben wie bei Verwendung des IN-Prädikats. Beachten Sie, dass der an das "where" der Unterabfrage übergebene Lambda-Ausdruck anstelle der äußeren "c" -Instanz die vom Parameter übergebene "c2" -Instanz verwendet.

  public List<Employee> selectByDepartmentName_exists(String departmentName) {
    Employee_ e = new Employee_();
    Department_ d = new Department_();
    return entityql
        .from(e)
        .where(
            c ->
                c.exists(
                    c.from(d)
                        .where(
                            c2 -> {
                              c2.eq(e.departmentId, d.id);
                              c2.eq(d.name, departmentName);
                            })))
        .fetch();
  }

Wenn der Parameter "departmentName" "SALES" ist, sieht das generierte SQL folgendermaßen aus:

select
    t0_.id,
    t0_.name,
    t0_.DEPARTMENT_ID
from
    Employee t0_
where
    exists (
        select
            t1_.id,
            t1_.name
        from
            Department t1_
        where
            t0_.DEPARTMENT_ID = t1_.id 
            and
            t1_.name = 'SALES'
    )

Die Methode "notExists", die dem Prädikat NOT EXISTS entspricht, wird ebenfalls bereitgestellt.

Erzielen Sie gleichwertige Suchergebnisse mit der JOIN-Klausel

Abfragen, die keine Unterabfragen sind, aber gleichwertige Suchergebnisse erhalten, können auch mithilfe von Joins dargestellt werden. Sie müssen sich nicht um die Vorsichtsmaßnahmen (Lambda-Ausdrucksparameter) kümmern, die bei der Verwendung von IN-Prädikaten und EXISTS-Prädikaten erforderlich sind. Wenn die Ergebnisse identisch sind, wird diese Methode empfohlen. In diesem Beispiel wird die Methode "innerJoin" aufgerufen.

  public List<Employee> selectByDepartmentName_join(String departmentName) {
    Employee_ e = new Employee_();
    Department_ d = new Department_();
    return entityql
        .from(e)
        .innerJoin(d, on -> on.eq(e.departmentId, d.id))
        .where(c -> c.eq(d.name, departmentName))
        .fetch();
  }

Wenn der Parameter "departmentName" "SALES" ist, sieht das generierte SQL folgendermaßen aus:

select
    t0_.id,
    t0_.name,
    t0_.DEPARTMENT_ID 
from
    Employee t0_
inner join
    Department t1_
on 
    (t0_.DEPARTMENT_ID = t1_.id)
where
    t1_.name = 'SALES'

Wenn in Kotlin geschrieben

Insbesondere bei Unterabfragen neigt der Code dazu, etwas chaotisch zu werden. Wenn Sie über diesen Punkt besorgt sind, können Sie in Kotlin schreiben. (Doma bietet Kriterien-API für Kotlin) Wenn Sie in Kotlin eine Methode schreiben, die der oben genannten entspricht, wird sie insgesamt aktualisiert, und Sie müssen sich keine Gedanken über die Parameter machen, die im Lambda-Ausdruck übergeben werden.

Unten finden Sie ein Codebeispiel, das in Kotlin geschrieben wurde. Wenn Sie jedoch interessiert sind, lesen Sie bitte auch dieses Projekt. Ich habe einen vollständigeren Beispielcode.

Beispiel mit IN-Prädikat

    fun selectByDepartmentName_in(departmentName: String): List<Employee> {
        val e = Employee_()
        val d = Department_()
        return entityql
            .from(e)
            .where {
                `in`(e.departmentId, from(d).where { eq(d.name, departmentName) }.select(d.id))
            }
            .fetch()
    }

Beispiel mit EXISTS-Prädikat

    fun selectByDepartmentName_exists(departmentName: String): List<Employee> {
        val e = Employee_()
        val d = Department_()
        return entityql
            .from(e)
            .where {
                exists(
                    from(d).where {
                        eq(e.departmentId, d.id)
                        eq(d.name, departmentName)
                    }
                )
            }
            .fetch()
    }

Beispiel mit der JOIN-Klausel

    fun selectByDepartmentName_join(departmentName: String): List<Employee> {
        val e = Employee_()
        val d = Department_()
        return entityql
            .from(e)
            .innerJoin(d) { eq(e.departmentId, d.id) }
            .where {
                eq(d.name, departmentName)
            }
            .fetch()
    }

abschließend

Demonstriert, wie Unterabfragen in der Kriterien-API von Doma 2.43.0 dargestellt werden.

In diesem Artikel ist der Java-Code im Google-Java-Format und der Kotlin-Code im ktlint-Format formatiert. Möglicherweise möchten Sie die Formatierung jedoch etwas anpassen, um die Lesbarkeit des Codes zu verbessern. Persönlich habe ich den Eindruck, dass das Google-Java-Format ein Format mit einigen Zeilenumbrüchen um den Lambda-Ausdruck hat.

Recommended Posts