Présentation de l'API des critères

Il existe deux manières d'écrire des requêtes de base de données dans Hibernate :

  • Langage de requête Hibernate
  • API de critères

Vous avez déjà rencontré le premier il y a longtemps, il est temps de vous familiariser avec l'API Criteria. C'est un outil très puissant, à un moment donné, il était encore plus populaire que HQL. Maintenant, ce n'est plus aussi populaire, mais pour certaines tâches, ce sera certainement une meilleure solution que HQL.

Dans tous les cas, vous ne pouvez pas apprendre Hibernate sans vous familiariser avec l'API Criteria. Écrivons un petit exemple, puis nous l'analyserons. Par exemple, nous demanderons tous les employés (Employé) de la base de données. Voici ce que nous obtiendrons :

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Employee> critQuery = builder.createQuery(Employee.class);

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Query<Employee> query = session.createQuery(critQuery);
List<Employee> results = query.getResultList();

Ça a l'air compliqué. Écrivons la même requête HQL pour comparaison :

String hqlQuery = "from Employee";

Query<Employee> query = session.createQuery(hqlQuery);
List<Employee> results = query.getResultList();

Notez que les deux dernières lignes des deux exemples sont presque identiques : nous créons un objet Query et l'utilisons pour obtenir une List. Cela laisse entendre que le reste des lignes font quelque chose d'identique.

Regardez les lignes 3 et 4 du premier exemple :

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Écrivons-les en une seule ligne :

critQuery.select(critQuery.from(Employee.class));

Cela ne vous rappelle rien ? Et si vous le coloriez un peu différemment :

critQuery.select(critQuery.from(Employee.class));

Oui, c'est une construction si délicate de la requête SELECT FROM.

Exemples d'utilisation de l'API Criteria

Pour une meilleure compréhension, je me contenterai de donner quelques exemples.

Demande 1 . Obtenez tous les employés avec un salaire supérieur à 10 000 :

critQuery.select(critQuery.from(Employee.class)).where(builder.gt(root.get("salary"), 10000));

Demande 2 . Obtenez tous les employés avec un salaire inférieur à 50 000:

critQuery.select(critQuery.from(Employee.class)).where(builder.lt(root.get("salary"), 50000));

Demande 3 . Obtenez tous les employés dont le titre de poste contient le mot "test":

critQuery.select(critQuery.from(Employee.class)).where(builder.like(root.get("occupation"), "%test%"));

Demande 4 . Obtenez tous les employés avec un salaire de 10 à 50 mille:

critQuery.select(critQuery.from(Employee.class)).where(builder.between(root.get("salary"), 10000, 50000));

Demande 5 . Obtenez tous les employés dont le nom est nul :

critQuery.select(critQuery.from(Employee.class)).where(builder.isNull(root.get("name")));

Demande 6 . Obtenez tous les employés dont le nom n'est pas nul :

critQuery.select(critQuery.from(Employee.class)).where(builder.isNotNull(root.get("name")));

C'est juste une façon délicate de construire une requête :

  • Vous obtenez d'abord l'objetGénérateur de critères.
  • Utilisez-le ensuite pour créer un objetCritèresRequête.
  • Ensuite, vous commencez à y ajouter des pièces avecCritèresRequêteEtGénérateur de critères.

Voici comment définir les paramètres pour :

  • SÉLECTIONNER
  • DEPUIS

Utilisant égalementGénérateur de critèresvous pouvez construire différentes conditions pour WHERE.

Travail avancé avec l'API Criteria

À l'aide de l'API Criteria, vous pouvez créer une requête de n'importe quelle complexité. Et c'est une excellente nouvelle. Par exemple, vous voulez une clause WHERE complexe. Voici comment procéder :

Predicate greaterThan = builder.gt(root.get("salary"), 1000);
Predicate testers = builder.like(root.get("occupation"), "test%");

critQuery.select(critQuery.from(Employee.class)).where(builder.or(greaterThan, testers));

Si vous voulez écrire AND au lieu de OR, alors vous n'avez qu'à changer la dernière ligne :

critQuery.select(critQuery.from(Employee.class)).where(builder.and(greaterThan, testers));

Tout est en fait très simple. Laissez-moi vous donner un tableau avec quelques comparaisons :

SQL Méthode Dossier complet
un<b lt(a, b) constructeur.lt(a, b)
un > b gt(a, b) constructeur.gt(a, b)
a ou B ou(a,b) constructeur.ou(a, b)
un ET b et(a,b) constructeur.et(a,b)
un J'AIME b comme (a, b) constructeur.like(a, b)
a ENTRE (c, d) entre (a, c, d) constructeur.entre(a, c, d)
a EST NULL estNul(a) builder.isNull(a)
a N'EST PAS NULL n'est pas nul(a) builder.isNotNull(a)

Tout est simple, n'est-ce pas ?

Et comment ajoutons-nous le tri à la requête ? Très simple:

critQuery.select( critQuery.from(Employee.class) );
critQuery.where( builder.and(greaterThan, testers) );
critQuery.orderBy( builder.asc(root.get("salary"), builder.desc(root.get("joinDate") )

Vous appelez simplement l'objetCritèresRequêteorderBy () et transmettez-lui les paramètres requis.

Voici à quoi ressemblerait la même requête dans HQL. Comparer:

select * from Employee
where (…) and (…)
order by 'salary' asc, 'joinDate' desc

Il suffit de retenir 3 choses :

  • Les opérateurs clés comme SELECT, FROM, WHERE sont appelés sur un objetCritèresRequête.
  • Les opérateurs auxiliaires comme AND, OR, DESC sont appelés sur l'objetGénérateur de critères.
  • Les noms de champs sont extraits de l'objet via get()racine.