En SQLLangage permettant de communiquer avec une base de données., lorsqu’une requête possède la clause GROUP BY, les champs mentionnés dans la clause SELECT ne peuvent être que :
En clair, je ne peux pas mentionner dans mon SELECT une colonne sur laquelle je ne groupe pas. La plupart du temps ce genre de requête n’a aucun sens, mais il arrive que ce soit moins évident. Dans ces cas-là, il faut s’en remettre à ses souvenirs de SQL classique.
Pourquoi le préciser ici ? Parce qu’au même titre que MySQLMoteur de gestion de base de données. est ultra-laxiste sur la syntaxe des requêtes utilisant la clause GROUP BY, Hibernate ne verra pas d’inconvénient à générer des requêtes qui n’ont pas de sens. Mais tous les SGBD ne sont pas comme ça, et s’il vous arrivait de passer d’un MySQL à Oracle, mieux vaut pour vous que vous n’ayez pas à réécrire toutes les requêtes de votre application… car Oracle, lui, ne plaisante pas avec les GROUP BY.
Si vous savez faire une requête simple avec Hibernate 4, l’utilisation du GROUP BY va vous paraître un jeu d’enfant. Il suffit d’utiliser la méthode groupBy() de votre CriteriaQuery, à laquelle vous passez en paramètre le champ sur lequel vous voulez grouper.
Exemple : la liste des numéros de commande groupés par eux-même :
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<
String> criteriaQuery = builder.createQuery(String.class);
Root<
Commande> root = criteriaQuery.from(Commande.class);
criteriaQuery.select(root.get(Commande_.numero));
criteriaQuery.groupBy(root.get(Commande_.numero));
TypedQuery<
String> typedQuery = entityManager.createQuery(criteriaQuery);
List<
String> result = typedQuery.getResultList();
C’est seulement pour le principe car cette requête n’a aucun intérêt. En général on cherche une information qui n’est pas spécifiquement dans la colonne du GROUP BY.
Un exemple plus pertinent : le nombre de commandes par jour :
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<
Tuple> criteriaQuery = builder.createQuery(Tuple.class);
Root<
Commande> root = criteriaQuery.from(Commande.class);
criteriaQuery.multiselect(root.get(Commande_.date), builder.count(root));
criteriaQuery.groupBy(root.get(Commande_.date));
TypedQuery<
Tuple> typedQuery = entityManager.createQuery(criteriaQuery);
List<
Tuple> result = typedQuery.getResultList();
On a ici un exemple certes un peu complexe mais plus intéressant qui mêle l’utilisation du GROUP BY, de la fonction d’agrégat COUNT() et du multiselect() (si vous n’êtes pas familier avec cette notion, voyez l’article qui lui est dédié).
Remarquez que vous pouvez spécifier plusieurs colonnes de regroupement. Exemple : la liste des commandes groupées par jour et par fournisseur :
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<
Tuple> criteriaQuery = builder.createQuery(Tuple.class);
Root<
Commande> root = criteriaQuery.from(Commande.class);
criteriaQuery.multiselect(root.get(Commande_.date), root.get(Commande_.fournisseur), builder.count(root));
List<
Expression<?>> groupList = new ArrayList();
groupList.add(root.get(Commande_.date));
groupList.add(root.get(Commande_.fournisseur));
criteriaQuery.groupBy(groupList);
TypedQuery<
Tuple> typedQuery = entityManager.createQuery(criteriaQuery);
List<
Tuple> result = typedQuery.getResultList();
Dans cet article, nous allons plonger dans le monde d'Hibernate 6, en commençant par reprendre les bases d’Hibernate et ses principaux concepts. Nous explorerons ensuite les nouveautés et les améliorations apportées par Hibernate 6.
Configuration pour l’installation du CAS jasig sur un serveur JBoss 7. Problème de loggeur, log4j et hibernate dialect
Le big data occupe de plus en plus d’espace dans l’actualité, et grâce au lobbying des grands acteurs de l’informatique, plus aucun client n’est épargné par ces campagnes d’évangélisation. Tout naturellement, une sorte de honte (virtuelle, d’ailleurs, ca