Es gibt mehrere Auswertungselemente für die Datenbankzugriffsbibliothek, aber ich denke, dass die einfache Zusammenstellung von dynamischem SQL ein Element mit hoher Priorität ist. Es ist einfach, statisches SQL zu schreiben, aber es ist leicht, Probleme zu bekommen, wenn es um dynamisches SQL geht. Insbesondere bei Geschäftsanwendungen werden mehrere Suchelemente auf dem Bildschirm angezeigt. Wenn dies angegeben ist, ist es in den Suchbedingungen enthalten. Wenn es nicht angegeben ist, ist es nicht enthalten, aber abhängig von der von der Bibliothek bereitgestellten Funktion der Anwendungscode Ist voll von bedingten Zweigen, was die Lesbarkeit verringert.
In diesem Artikel wird die Möglichkeit vorgestellt, SQL WHERE-Klauseln mithilfe der API 2.oma 2.43.0 Criteria dynamisch zusammenzustellen und wie Doma die oben genannten Probleme löst. Gibt an, ob es behoben werden kann.
Eine Übersicht über Doma und die Kriterien-API finden Sie auch unter Einführung in Doma - Einführung in die Kriterien-API.
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 Klasse "Mitarbeiter" als Entitätsklasse vor, die der Mitarbeitertabelle entspricht.
Employee.java
@Entity(metamodel = @Metamodel)
public class Employee {
@Id
public Integer id;
public String name;
public Integer age;
@Version public Integer version;
}
Bereiten Sie "EmployeeRepository" als Repository vor, um nach Mitarbeitern nach Alter zu suchen.
Bei der Suche wird davon ausgegangen, dass die oberen und unteren Altersgrenzen als Optionen angegeben werden können (falls angegeben, ist sie in der Suchbedingung enthalten, wenn nicht angegeben, ist sie nicht enthalten), und diese Funktion wird von der Methode selectByAgeRange
implementiert.
EmployeeRepository.java
public class EmployeeRepository {
private final Entityql entityql;
public EmployeeRepository(Config config) {
this.entityql = new Entityql(config);
}
public List<Employee> selectByAgeRange(Integer min, Integer max) {
//Der Schwerpunkt dieses Artikels liegt auf der Implementierung mit der Kriterien-API.
}
}
Die Kriterien-API von Doma kann eine Suchbedingung automatisch aus der WHERE-Klausel ausschließen, wenn Sie eine Suchbedingung angeben, die mit null verglichen werden soll. Wenn Sie diese Funktion verwenden, müssen Sie daher die bedingte Verzweigung in der Implementierung von selectByAgeRange
nicht beschreiben. Es kann wie folgt implementiert werden:
EmployeeRepository.Ein Teil von Java
public List<Employee> selectByAgeRange(Integer min, Integer max) {
Employee_ e = new Employee_();
return entityql
.from(e)
.where(
c -> {
c.ge(e.age, min);
c.le(e.age, max);
})
.fetch();
}
Im Folgenden sehen wir uns die SQL an, die generiert wird, wenn Sie diese Methode in einem bestimmten Muster aufrufen.
Im Folgenden repräsentiert "Repository" eine Instanz der "EmployeeRepository" -Klasse.
List<Employee> list = repository.selectByAgeRange(30, 40);
Das zu diesem Zeitpunkt generierte SQL lautet wie folgt. Suchbedingungen, die die oberen und unteren Altersgrenzen angeben, werden in der WHERE-Klausel ordnungsgemäß angezeigt.
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.age >= ? and t0_.age <= ?
List<Employee> list = repository.selectByAgeRange(30, null);
Die Suchbedingung, die die Obergrenze angibt, wird in der WHERE-Klausel nicht angezeigt.
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.age >= ?
List<Employee> list = repository.selectByAgeRange(null, 40);
Dieses Mal wird die Suchbedingung, die die Untergrenze angibt, nicht in der WHERE-Klausel angezeigt.
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.age <= ?
List<Employee> list = repository.selectByAgeRange(null, null);
Sie können vorhersagen, wie das Ergebnis aussehen wird. Ja, es werden auch keine Suchkriterien angezeigt, die die oberen und unteren Grenzen angeben.
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_
Wie sollten Sie also schreiben, wenn Sie Werte ungleich Null anzeigen und entscheiden möchten, ob Sie diese in Ihre Suchkriterien aufnehmen möchten? Angenommen, es besteht die Anforderung, dass die untere Altersgrenze, wenn sie 0 oder weniger beträgt, nicht in der Bedingung enthalten ist (nur wenn sie größer als 0 ist, ist sie in der Bedingung enthalten). In diesem Fall können Sie einen expliziten bedingten Zweig wie folgt schreiben.
EmployeeRepository.Ein Teil von Java
public List<Employee> selectByAgeRange(Integer min, Integer max) {
Employee_ e = new Employee_();
return entityql
.from(e)
.where(
c -> {
if (min != null && min > 0) {
c.ge(e.age, min);
}
c.le(e.age, max);
})
.fetch();
}
Die bedingte Verzweigung erfolgt im Lambda-Ausdrucksblock, der einfach an die where-Methode übergeben wird. Sofern die Bedingung nicht ausgewertet wird, wird sie nicht in die Suchbedingung aufgenommen.
List<Employee> list = repository.selectByAgeRange(-1, 40);
Wenn Sie es wie oben aufrufen, werden Sie feststellen, dass die folgende SQL generiert wird und die Suchbedingung, die die Untergrenze angibt, nicht in der WHERE-Klausel angezeigt wird.
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.age <= ?
In diesem Artikel habe ich Ihnen gezeigt, wie Sie die Kriterien-API von Doma verwenden, um dynamische WHERE-Klauseln in SQL präzise zu erstellen.
Es ist nicht genau das gleiche wie hier gezeigt, aber ähnlicher Code befindet sich im folgenden Projekt und kann ausgeführt und ausprobiert werden.