[JAVA] Premiers pas avec Doma-Dynamic Construction de clauses WHERE avec l'API Criteria

introduction

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.

Exemple de code utilisé dans cet article

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éthodeselectByAgeRange`.

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.
  }
}

Fonction de suppression automatique des conditions de recherche pour comparer avec null

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.

Lors du passage d'une valeur non nulle à min et max

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 <= ?

Lors du passage de non-null à min et de null à max

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 >= ?

Lors du passage de null à min et non nul à max

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 <= ?

Lors du passage de null à min et max

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_

Branchement conditionnel explicite dans un bloc

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 <= ?

en conclusion

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

Premiers pas avec Doma-Dynamic Construction de clauses WHERE avec l'API Criteria
Premiers pas avec les sous-requêtes utilisant Doma avec l'API Criteria
Premiers pas avec Doma - Introduction à l'API Criteria
Premiers pas avec Doma-Using Projection avec l'API Criteira
Premiers pas avec Doma-Using Joins avec l'API Criteira
Prise en main des opérateurs logiques utilisant Doma tels que AND et OR dans la clause WHERE de l'API Criteria
Premiers pas avec Reactive Streams et l'API JDK 9 Flow
Premiers pas avec Doma-Criteria API Cheet Sheet
Démarrez avec le fonctionnement de JVM GC
Premiers pas avec DBUnit
Premiers pas avec Ruby
Premiers pas avec Swift
Premiers pas avec Doma-Transactions
Premiers pas avec le traitement Doma-Annotation
Premiers pas avec Java Collection
Premiers pas avec JSP et servlet
Premiers pas avec les bases de Java
Premiers pas avec Spring Boot
Il est maintenant temps de commencer avec l'API Stream
Premiers pas avec les modules Ruby
Résumer les principaux points de démarrage avec JPA appris avec Hibernate
Premiers pas avec Java_Chapitre 5_Exercices pratiques 5_4
[Google Cloud] Premiers pas avec Docker
Premiers pas avec Docker avec VS Code
Premiers pas avec Ruby pour les ingénieurs Java
Premiers pas avec Docker pour Mac (installation)
Introduction au test de paramétrage dans JUnit
Introduction à Java à partir de 0 Partie 1
Premiers pas avec Ratpack (4) - Routage et contenu statique
Premiers pas avec Language Server Protocol avec LSP4J
Premiers pas avec la création d'ensembles de ressources avec ListResoueceBundle