Construction de requêtes en Java : comment faire le bon choix ?

Dans toutes les applications, il faut à un moment ou un autre, aller requêter en base de données. Certaines requêtes sont relativement simples
mais d'autres peuvent être plus complexes et dans ce cas là, plusieurs frameworks sont disponibles pour écrire ces requêtes.
Parmi toutes les solutions de requêtage disponibles (Spring Data - JPA, Criteria Hibernate, Criteria JPA2, JPQL, QueryDSL), comment faire le bon choix ?

Pour toutes les requêtes simples, Spring Data - JPA est celui qu'il faut retenir.
Pourquoi ? Tout simplement car il permet de faire directement le travail pour vous !!
Spring Data - JPA se base sur la notion de Repository et l'approche DDD (Domain Driven Design). Nul besoin pour le développeur d'écrire explicitement de requête, Spring Data le fait automatiquement à partir du nom des méthodes écrites dans l'interface de Repository.

Un Repository est une interface contenant :

  • Des méthodes spécifiques de recherche (intégration des restrictions et des critères de requêtes directement dans le nom et paramètres des méthodes)
  • Toutes les fonctions basiques de CRUD (save, delete, findById, count, exists, findAll...) à travers l'héritage

Exemple : comment écrire un Repository permettant de gérer les utilisateurs ?
En créant une interface UtilisateurRepository qui hérite de l'interface JpaRepository de l'API.
Le framework se charge alors lui-même de fournir une implémentation du Repository des utilisateurs au démarrage du contexte Spring.

UtilisateurRepository

Spring Data - JPA est :

  • intuitif : les conventions de nommage pour l'écriture des requêtes sont rapidement assimilées
  • simple d'utilisation : la définition des repositories consiste à écrire uniquement des interfaces
  • productif : une prise en charge de toutes les opérations basiques de CRUD et de la plupart des requêtes d'une application
  • évolutif avec la possibilité de rédéfinir une couche repository personnalisée pour y intégrer de nouveaux comportements

Pour les requêtes plus complexes, plusieurs solutions existent : Criteria Hibernate, Criteria JPA2, QueryDSL.

L'utilisation des Criteria Hibernate impose de bien connaître l'API et ses subtilités pour arriver à produire la requête voulue (jonglage entre plusieurs notions de Restrictions, Disjunction, DetachedCriteria...). L'utilisation de ces objets oblige à passer directement en chaîne de caractères le nom des attributs pour poser des restrictions. Les erreurs sont donc assez fréquentes lors du développement (faute de frappe) et lors des opérations de refactoring. Et, comme ces erreurs se passent au moment de l'exécution, elles sont souvent détectées tardivement.

Partant de ce constat, la communauté Hibernate a sorti une nouvelle API de criteria (Criteria JPA2) qui se veut "type-safe" et fortement typée. L'API se base sur un méta-model statique généré par annotation processor pour permettre de détecter les erreurs de requêtes directement lors de la phase de compilation.
Concrètement, grâce à un plugin maven, pour chaque entité métier, Hibernate va construire le méta-model associé. Pour une entité métier "Utilisateur", le méta-model associé sera "Utilisateur_" contenant l'ensemble des attributs accessibles en static pour la construction des requêtes.

QueryDSL est un framework qui permet, tout comme les Criteria JPA2 d'écrire des requêtes "type-safe", évitant ainsi les désagréments lors des phases de refactoring et permettant aux développeurs de bénéficier de l'autocomplétion dans l'IDE. QueryDSL propose des solutions quel que soit l'outil de persistance choisi (JPA, JDO...) et quelle que soit la base (relationnelle ou non, SQL-NoSQL, Lucene). Dans ce post et dans l'exemple téléchargeable, c'est la persistance via JPA qui est abordée. Le principe est le même que pour les Criteria JPA2 : chaque entité métier va être associée à une classe de méta-model correspondante grâce à l'APT (Annotation Processor Tool).
Pour QueryDSL, la classe générée se nommera "QUtilisateur" pour une entité métier "Utilisateur".
La syntaxe de construction des requêtes avec QueryDSL est moins verbeuse, plus rapide à assimiler et plus lisible que celle proposée par les Criteria JPA2. Vous pourrez d'ailleurs trouver sur le site de QueryDSL un comparatif entre l'écriture d'une requête Criteria JPA2 vs QueryDSL.

Exemple : Requêtes avec QueryDSL

UtilisateurQuery

Le code source et la configuration du projet querybuilding utilisés pour illustrer ce post sont téléchargeables ici.

Documentations : Criteria Hibernate | Spring Data - JPA | QueryDSL

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.