Guide de Querydsl avec JPA

1. Vue d'ensemble

Querydsl est un framework Java complet, qui permet de créer et d'exécuter des requêtes de type sécurisé dans un langage spécifique à un domaine similaire à SQL .

Dans cet article, nous allons explorer Querydsl avec l'API Java Persistence.

Une remarque rapide ici est que HQL pour Hibernate était le premier langage cible pour Querydsl, mais de nos jours, il prend en charge JPA, JDO, JDBC, Lucene, Hibernate Search, MongoDB, Collections et RDFBean en tant que backends.

2. Préparatifs

Ajoutons d'abord les dépendances nécessaires dans notre projet Maven:

 2.5.0   com.querydsl querydsl-apt ${querydsl.version} provided   com.querydsl querydsl-jpa ${querydsl.version}   org.slf4j slf4j-log4j12 1.6.1 

Et maintenant, configurons le plugin Maven APT:

   ...  com.mysema.maven apt-maven-plugin 1.1.3    process   target/generated-sources com.querydsl.apt.jpa.JPAAnnotationProcessor     ...   

Le JPAAnnotationProcessor trouvera les types de domaine annotés avec l' annotation javax.persistence.Entity et génère des types de requête pour eux.

3. Requêtes avec Querydsl

Les requêtes sont construites en fonction des types de requête générés qui reflètent les propriétés de vos types de domaine. Les invocations de fonction / méthode sont également construites de manière totalement sécurisée.

Les chemins de requête et les opérations sont les mêmes dans toutes les implémentations et les interfaces de requête ont également une interface de base commune.

3.1. Une entité et le type de requête Querydsl

Définissons d'abord une entité simple que nous allons utiliser au fil des exemples:

@Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column private String firstname; @Column private String surname; Person() { } public Person(String firstname, String surname) { this.firstname = firstname; this.surname = surname; } // standard getters and setters }

Querydsl générera un type de requête avec le nom simple QPerson dans le même package que Person . QPerson peut être utilisé comme variable de type statique dans les requêtes Querydsl en tant que représentant du type Person .

Premièrement - QPerson a une variable d'instance par défaut accessible en tant que champ statique:

QPerson person = QPerson.person;

Vous pouvez également définir vos propres variables Person comme ceci:

QPerson person = new QPerson("Erich", "Gamma");

3.2. Créer une requête à l'aide de JPAQuery

Nous pouvons désormais utiliser des instances JPAQuery pour nos requêtes:

JPAQuery query = new JPAQuery(entityManager);

Notez que le entityManager est une Assemblée parlementaire paritaire EntityManager .

Récupérons maintenant toutes les personnes portant le prénom « Kent » comme exemple rapide:

QPerson person = QPerson.person; List persons = query.from(person).where(person.firstName.eq("Kent")).list(person);

L' appel from définit la source de la requête et la projection, la partie where définit le filtre et la liste indique à Querydsl de renvoyer tous les éléments correspondants.

Nous pouvons également utiliser plusieurs filtres:

query.from(person).where(person.firstName.eq("Kent"), person.surname.eq("Beck"));

Ou:

query.from(person).where(person.firstName.eq("Kent").and(person.surname.eq("Beck")));

Dans la forme native JPQL, la requête serait écrite comme ceci:

select person from Person as person where person.firstName = "Kent" and person.surname = "Beck"

Si vous souhaitez combiner les filtres via "ou", utilisez le modèle suivant:

query.from(person).where(person.firstName.eq("Kent").or(person.surname.eq("Beck")));

4. Classement et agrégation dans Querydsl

Voyons maintenant comment la commande et l'agrégation fonctionnent dans la bibliothèque Querydsl.

4.1. Commande

Nous commencerons par classer nos résultats par ordre décroissant par le champ nom :

QPerson person = QPerson.person; List persons = query.from(person) .where(person.firstname.eq(firstname)) .orderBy(person.surname.desc()) .list(person);

4.2. Agrégation

Utilisons maintenant une simple agrégation, car nous en avons quelques-unes disponibles (Sum, Avg, Max, Min):

QPerson person = QPerson.person; int maxAge = query.from(person).list(person.age.max()).get(0);

4.3. Agrégation avec GroupBy

La classe com.mysema.query.group.GroupBy fournit une fonctionnalité d'agrégation que nous pouvons utiliser pour agréger les résultats de la requête en mémoire.

Voici un exemple rapide où le résultat est renvoyé sous forme de carte avec le prénom comme clé et l' âge maximum comme valeur:

QPerson person = QPerson.person; Map results = query.from(person).transform( GroupBy.groupBy(person.firstname).as(GroupBy.max(person.age)));

5. Test avec Querydsl

Maintenant, définissons une implémentation DAO à l'aide de Querydsl - et définissons l'opération de recherche suivante:

public List findPersonsByFirstnameQuerydsl(String firstname) { JPAQuery query = new JPAQuery(em); QPerson person = QPerson.person; return query.from(person).where(person.firstname.eq(firstname)).list(person); }

Et maintenant, construisons quelques tests en utilisant ce nouveau DAO et utilisons Querydsl pour rechercher des objets Person nouvellement créés (implémentés dans la classe PersonDao ) et dans une autre agrégation de test à l'aide de la classe GroupBy est testée:

@Autowired private PersonDao personDao; @Test public void givenExistingPersons_whenFindingPersonByFirstName_thenFound() { personDao.save(new Person("Erich", "Gamma")); Person person = new Person("Kent", "Beck"); personDao.save(person); personDao.save(new Person("Ralph", "Johnson")); Person personFromDb = personDao.findPersonsByFirstnameQuerydsl("Kent").get(0); Assert.assertEquals(person.getId(), personFromDb.getId()); } @Test public void givenExistingPersons_whenFindingMaxAgeByName_thenFound() { personDao.save(new Person("Kent", "Gamma", 20)); personDao.save(new Person("Ralph", "Johnson", 35)); personDao.save(new Person("Kent", "Zivago", 30)); Map maxAge = personDao.findMaxAgeByName(); Assert.assertTrue(maxAge.size() == 2); Assert.assertSame(35, maxAge.get("Ralph")); Assert.assertSame(30, maxAge.get("Kent")); }

6. Conclusion

Ce didacticiel a illustré comment créer un projet JPA à l'aide de Querydsl.

L' implémentation complète de cet article se trouve dans le projet github - il s'agit d'un projet maven basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.

Une note rapide ici est - exécutez une simple compilation maven (mvn clean install) pour générer les types dans les sources cibles / générées - puis, si vous utilisez Eclipse - incluez le dossier comme dossier source du projet.