Objectif
CriteriaQuery permet d’assembler la requête complète
Après avoir compris CriteriaBuilder, l’étape suivante est de maîtriser CriteriaQuery.
Qu’est-ce que CriteriaQuery ?
CriteriaQuery est une interface qui permet de construire une requête typée. Elle représente donc la requête elle-même, c’est-à-dire la structure globale :
- Définition de la source (
.from()) : elle renvoie un objet Root, qui représente cette entité dans la requête et permet d’accéder aux attributs de celle-ci. - Les sélections (
.select()) : pour définir les champs à récupérer. - Les filtres (
.where()) : pour appliquer des conditions de filtrage. - Les jointures (
.join()) : pour lier plusieurs entités. - Les tris (
.orderBy()) : pour ordonner les résultats. - Les agrégations (
.groupBy(),.having()) : pour grouper et appliquer des conditions sur les groupes.
Comment obtenir un CriteriaQuery ?
Depuis un CriteriaBuilder on obtient une instance typé Une requête Criteria suit toujours ce schéma :
- CriteriaBuilder
- CriteriaQuery
- Root
- select
- where
- TypedQuery
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);Quelques méthodes
L’ensemble des méthodes est disponible dans la Javadoc. Ci-dessous nous en présentons quelques une.
| Méthode | JavaDoc officielle | Signature |
|---|---|---|
from() | Crée et ajoute une racine de requête correspondant à l’entité donnée, formant ainsi la clause FROM. | <X> Root<X> from(Class<X> entityClass) |
select() | Spécifie l’élément à retourner dans le résultat de la requête. Remplace toute sélection précédente. | CriteriaQuery<T> select(Selection<? extends T> selection) |
where() | Modifie la requête pour appliquer les restrictions données. Remplace toute restriction précédente. | CriteriaQuery<T> where(Expression<Boolean> restriction) |
groupBy() | Spécifie les expressions utilisées pour regrouper les résultats de la requête. Remplace tout groupement précédent. | CriteriaQuery<T> groupBy(Expression<?>... grouping) |
1. Définir la racine : from
// Equivalent SQL : FROM User u
Root<User> root = query.from(User.class);Soit nous exploitons directement l’objet root dans un select, par exemple query.select(root);. Soit nous pouvons créer une jointure
Jointures : join
// Join<Source, Destination>
Join<User, Department> dept = root.join("department");
query.where(cb.equal(dept.get("name"), "IT"));2. Sélectionner des résultats : select
// Equivalent SQL : SELECT u
query.select(root);Sélectionner un champ précis
On retombe sur l’expression de la page précédente : Expression<String> nameExp = root.get("name");
query.select(root.get("name"));3. Exécution avec TypedQuery
Une fois la requête terminée
TypedQuery<User> typedQuery = em.createQuery(query);
List<User> results = typedQuery.getResultList();Exemple complet
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> root = query.from(User.class);
Predicate active = cb.equal(root.get("active"), true);
Predicate adult = cb.greaterThan(root.get("age"), 18);
query.select(root)
.where(cb.and(active, adult))
.orderBy(cb.asc(root.get("name")));
List<User> users = em.createQuery(query).getResultList();