Lors de la construction de la clause WHERE de SQL, pour spécifier plusieurs conditions, il est nécessaire de concaténer avec des opérateurs logiques tels que AND et OR. Cet article montre comment une telle concaténation d'opérateurs logiques peut être représentée par l'API Criteria dans Doma 2.43.0.
La concaténation d'opérateurs logiques est une fonction simple à exprimer en SQL, mais comment la réaliser en tant que langage de programmation est une question à considérer. La caractéristique de Doma est qu'elle peut être exprimée à l'aide d'une expression lambda.
Pour un aperçu de Doma et de l'API Criteria, lisez les autres articles dans Introduction à Doma.
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 Employé comme classe d'entité correspondant à la table Employé.
Employee.java
@Entity(metamodel = @Metamodel)
public class Employee {
@Id
public Integer id;
public String name;
public Integer age;
@Version public Integer version;
}
Nous préparerons ʻEmployeeRepositoryet réécrirons la méthode
select` de cette classe pour montrer quelques exemples.
public class EmployeeRepository {
private final Entityql entityql;
public EmployeeRepository(Config config) {
this.entityql = new Entityql(config);
}
public List<Employee> select() {
//Voici un exemple de code réécrit de différentes manières
}
}
Si vous listez les conditions de recherche (ʻeq (..., ...) ʻ dans cet exemple), elles sont implicitement concaténées par AND.
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();
Le SQL généré ressemble à ceci:
(Ci-après, le SQL avec la valeur liée incorporée est affiché, mais en réalité, le SQL est émis en utilisant la variable de liaison ?
.)
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.id = 1 and t0_.name = 'aaa' and t0_.age = 20
Dans l'exemple précédent, la méthode correspondant à AND n'a pas été appelée, mais il est également possible d'appeler explicitement la méthode ʻand correspondant à AND comme suit. La méthode ʻand
reçoit une expression lambda.
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();
Le SQL généré sera le suivant, et le même SQL que dans l'exemple précédent sera généré (cependant, il existe des différences telles que la présence ou l'absence de parenthèses).
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.id = 1 and (t0_.name = 'aaa') and (t0_.age = 20)
Pour concaténer par OR, appelez la méthode ʻor comme suit: La méthode ʻor
reçoit une expression lambda.
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();
Le SQL généré ressemble à ceci:
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.id = 1 or (t0_.name = 'aaa' and t0_.age = 20)
Similaire à l'exemple précédent, mais quel type de SQL le code suivant génère-t-il?
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();
Vous pourriez penser qu'un OR supplémentaire est généré immédiatement après la clause WHERE, mais Doma supprime automatiquement AND et OR au début de la clause WHERE, de sorte que le SQL suivant est généré.
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where (t0_.name = 'aaa' and t0_.age = 20) and t0_.id = 1
Cette fonction est utile lorsque la nécessité de AND ou OR n'est pas déterminée statiquement en raison d'une branche conditionnelle dans la clause WHERE.
Employee_ e = new Employee_();
return entityql.from(e).where(c -> {
if (Une certaine condition) {
c.or(() -> {
c.eq(e.name, "aaa");
c.eq(e.age, 20);
});
}
if (Une certaine condition 2) {
c.or(() -> {
c.eq(e.name, "bbb");
c.eq(e.age, 30);
});
}
}).fetch();
Vous pouvez imbriquer n'importe quel nombre de «et» et de «ou» sans aucune restriction.
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();
Le code ci-dessus générera le SQL suivant:
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))
J'ai montré comment la concaténation d'opérateurs logiques peut être exprimée dans l'API Criteria de Doma.
Comme mentionné au début, l'API Criteira de Doma exprime la concaténation d'opérateurs logiques sous la forme d'une expression lambda. Il existe une chaîne de méthodes comme autre méthode d'expression, mais je pense personnellement que la chaîne de méthodes a une faiblesse. Il est vulnérable au branchement conditionnel. S'il y a une branche conditionnelle, la chaîne se brisera et la complexité augmentera aussitôt. En effet, vous devez stocker l'objet à enchaîner dans une variable afin de connecter la chaîne. D'un autre côté, la méthode utilisant une expression lambda telle que l'API Criteria de Doma est simple et hautement lisible car il n'y a pas de différence de style d'écriture selon que le branchement conditionnel est inclus ou non (simplement parce qu'il est entouré de blocs if). Je pense.
Recommended Posts