Il existe plusieurs éléments d'évaluation pour la bibliothèque d'accès à la base de données, mais je pense que la facilité d'assemblage de SQL dynamique est un élément hautement prioritaire. Il est facile d'écrire du SQL statique, mais il est facile d'avoir des ennuis en matière de SQL dynamique. Surtout dans le cas des applications d'entreprise, il est nécessaire qu'il y ait plusieurs éléments de recherche à l'écran, et s'ils sont spécifiés, ils sont inclus dans les conditions de recherche et s'ils ne sont pas spécifiés, ils ne sont pas inclus. Est plein de branches conditionnelles, ce qui réduit la lisibilité.
Cet article présente la possibilité d'assembler dynamiquement des clauses SQL WHERE à l'aide de l'API de critères Doma 2.43.0 et comment Doma résout les problèmes ci-dessus. Indique s'il peut être résolu.
Pour un aperçu de Doma et de l'API Criteria, lisez également Introduction à Doma - Introduction à l'API Criteria.
La base de données n'a qu'une seule table d'employés qui représente les employés.
schema.sql
create table employee (
id integer not null primary key,
name varchar(255) not null,
age integer not null,
version integer not null);
Préparez la classe ʻEmployee` comme classe d'entité correspondant à la table des employés.
Employee.java
@Entity(metamodel = @Metamodel)
public class Employee {
@Id
public Integer id;
public String name;
public Integer age;
@Version public Integer version;
}
Préparez ʻEmployee Repositorycomme référentiel pour rechercher les employés par âge. Lors de la recherche, on suppose que les limites supérieure et inférieure de l'âge peuvent être spécifiées comme des options (si spécifié, il est inclus dans la condition de recherche, s'il n'est pas spécifié, il n'est pas inclus), et cette fonction est implémentée par la méthode
selectByAgeRange`.
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) {
//L'objectif de cet article est de savoir comment mettre en œuvre cela avec l'API Criteria.
}
}
L'API Criteria de Doma a la capacité d'exclure automatiquement une condition de recherche de la clause WHERE lorsque vous spécifiez une condition de recherche à comparer avec null. Par conséquent, si vous utilisez cette fonction, vous n'avez pas besoin de décrire le branchement conditionnel dans l'implémentation de selectByAgeRange
. Il peut être implémenté comme suit:
EmployeeRepository.Fait partie de 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();
}
Ci-dessous, nous examinerons le SQL généré lorsque vous appelez cette méthode dans un modèle.
Ci-après, repository
représente une instance de la classe ʻEmployeeRepository`.
List<Employee> list = repository.selectByAgeRange(30, 40);
Le SQL généré à ce moment est le suivant. Les conditions de recherche qui spécifient les limites d'âge supérieure et inférieure apparaissent correctement dans la clause WHERE.
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);
La condition de recherche qui spécifie la limite supérieure n'apparaît pas dans la clause WHERE.
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.age >= ?
List<Employee> list = repository.selectByAgeRange(null, 40);
Cette fois, la condition de recherche qui spécifie la limite inférieure n'apparaît pas dans la clause WHERE.
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.age <= ?
List<Employee> list = repository.selectByAgeRange(null, null);
Vous pouvez prédire quel sera le résultat. Oui, aucun des critères de recherche qui spécifient les limites supérieure et inférieure n'apparaîtra.
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_
Alors, comment devriez-vous écrire si vous voulez voir des valeurs non nulles et décider de les inclure dans vos critères de recherche? Par exemple, supposons que lorsque la limite inférieure d'âge est égale ou inférieure à 0, elle ne soit pas incluse dans la condition (uniquement lorsqu'elle est supérieure à 0, elle est incluse dans la condition). Dans ce cas, vous pouvez écrire une branche conditionnelle explicite comme suit.
EmployeeRepository.Fait partie de 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();
}
Le branchement conditionnel est effectué dans le bloc d'expression lambda qui est simplement passé à la méthode where. À moins que la condition ne soit évaluée, elle ne sera pas incluse dans la condition de recherche.
List<Employee> list = repository.selectByAgeRange(-1, 40);
Si vous l'appelez comme ci-dessus, vous verrez que le SQL suivant est généré et la condition de recherche qui spécifie la limite inférieure n'apparaît pas dans la clause WHERE.
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.age <= ?
Dans cet article, je vous ai montré comment utiliser l'API Criteria de Doma pour construire de manière concise des clauses WHERE dynamiques dans SQL.
Ce n'est pas exactement la même chose que celle illustrée ici, mais un code similaire peut être trouvé dans le projet ci-dessous et peut être exécuté et essayé.
Recommended Posts