En guide til Querydsl med JPA

1. Oversigt

Querydsl er en omfattende Java-ramme, som hjælper med oprettelse og kørsel typesikre forespørgsler på et domænespecifikt sprog, der ligner SQL.

I denne artikel udforsker vi Querydsl med Java Persistence API.

En hurtig sidebemærkning her er, at HQL for Hibernate var det første målsprog for Querydsl, men i dag understøtter det JPA, JDO, JDBC, Lucene, Hibernate Search, MongoDB, Collections og RDFBean som backends.

2. Forberedelser

Lad os først tilføje de nødvendige afhængigheder i vores Maven-projekt:

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

Og lad os nu konfigurere Maven APT-pluginet:

   ... com.mysema.maven apt-maven-plugin 1.1.3 procesmål / genererede kilder com.querydsl.apt.jpa.JPAAnnotationProcessor ... 

Det JPAAnnotationProcessor finder domænetyper, der er kommenteret med javax.persistence.Entity kommentar og genererer forespørgselstyper til dem.

3. Forespørgsler med Querydsl

Forespørgsler konstrueres baseret på genererede forespørgselstyper, der afspejler egenskaberne for dine domænetyper. Funktions- / metodeopkald er konstrueret på en fuldt typesikker måde.

Forespørgselsstierne og operationerne er de samme i alle implementeringer og også i Forespørgsel grænseflader har en fælles basisgrænseflade.

3.1. En enhed og Querydsl-forespørgselstypen

Lad os først definere en simpel enhed, som vi vil bruge, når vi gennemgår eksempler:

@Entity offentlig klasse Person {@Id @GeneratedValue (strategi = GenerationType.IDENTITY) privat Lang id; @Kolonne privat streng fornavn; @Kolonne privat streng efternavn; Person () {} offentlig person (streng fornavn, streng efternavn) {this.firstname = fornavn; dette. efternavn = efternavn; } // standard getters og setters}

Querydsl genererer en forespørgselstype med det enkle navn QPerson i samme pakke som Person. QPerson kan bruges som en statisk skrevet variabel i Querydsl - forespørgsler som repræsentant for Person type.

Første - QPerson har en standardinstansvariabel, som kan tilgås som et statisk felt:

QPerson person = QPerson.person;

Alternativt kan du definere din egen Person variabler som dette:

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

3.2. Byg forespørgsel ved hjælp af JPAQuery

Vi kan nu bruge JPAQuery forekomster af vores forespørgsler:

JPAQuery-forespørgsel = ny JPAQuery (entityManager);

Bemærk, at entityManager er en JPA EntityManager.

Lad os nu hente alle personer med fornavnet “Kent”Som et hurtigt eksempel:

QPerson person = QPerson.person; Listepersoner = forespørgsel.fra (person) .where (person.firstName.eq ("Kent")). Liste (person);

Det fra opkald definerer forespørgselskilde og projektion, hvor del definerer filteret og liste beder Querydsl om at returnere alle matchede elementer.

Vi kan også bruge flere filtre:

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

Eller:

query.from (person) .where (person.firstName.eq ("Kent"). og (person.sname.eq ("Beck")));

I native JPQL-form ville forespørgslen blive skrevet således:

vælg person fra person som person, hvor person.firstName = "Kent" og person.sname = "Beck"

Hvis du vil kombinere filtrene via “eller”, skal du bruge følgende mønster:

query.from (person) .where (person.firstName.eq ("Kent") eller (person.sname.eq ("Beck")));

4. Bestilling og aggregering i Querydsl

Lad os nu se på, hvordan bestilling og sammenlægning fungerer i Querydsl-biblioteket.

4.1. Bestilling

Vi starter med at bestille vores resultater i faldende rækkefølge efter efternavn Mark:

QPerson person = QPerson.person; Liste over personer = forespørgsel.fra (person) .hvor (person.fornavn.eq (fornavn)) .orderBy (person.navn.desc ()) .liste (person);

4.2. Aggregering

Lad os nu bruge en simpel sammenlægning, da vi har et par tilgængelige (Sum, Gns., Maks., Min):

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

4.3. Aggregering med GroupBy

Det com.mysema.query.group.GroupBy klasse giver aggregeringsfunktionalitet, som vi kan bruge til at samle forespørgselsresultater i hukommelsen.

Her er et hurtigt eksempel, hvor resultatet returneres som Kort med fornavn som nøgle og maks. alder som værdien:

QPerson person = QPerson.person; Kortresultater = forespørgsel.fra (person) .transform (GroupBy.groupBy (person.firstnavn) .as (GroupBy.max (person.alder)));

5. Test med Querydsl

Lad os nu definere en DAO-implementering ved hjælp af Querydsl - og lad os definere følgende søgning:

public List findPersonsByFirstnameQuerydsl (String firstname) {JPAQuery query = new JPAQuery (em); QPerson person = QPerson.person; returner forespørgsel. fra (person). hvor (person. fornavn. eq (fornavn)). liste (person); }

Og lad os nu bygge et par tests ved hjælp af denne nye DAO, og lad os bruge Querydsl til at søge efter nyoprettede Person objekter (implementeret i PersonDao klasse) og i en anden testaggregation ved hjælp af GroupBy klasse er testet:

@Autowired privat PersonDao personDao; @Test offentligt ugyldigt givetExistingPersons_whenFindingPersonByFirstName_thenFound () {personDao.save (ny person ("Erich", "Gamma")); Person person = ny person ("Kent", "Beck"); personDao.save (person); personDao.save (ny person ("Ralph", "Johnson")); Person personFromDb = personDao.findPersonsByFirstnameQuerydsl ("Kent"). Get (0); Assert.assertEquals (person.getId (), personFromDb.getId ()); } @ Test offentligt ugyldigt givetExistingPersons_whenFindingMaxAgeByName_thenFound () {personDao.save (ny person ("Kent", "Gamma", 20)); personDao.save (ny person ("Ralph", "Johnson", 35)); personDao.save (ny person ("Kent", "Zivago", 30)); Kort maxAge = personDao.findMaxAgeByName (); Assert.assertTrue (maxAge.size () == 2); Assert.assertSame (35, maxAge.get ("Ralph")); Assert.assertSame (30, maxAge.get ("Kent")); }

6. Konklusion

Denne vejledning illustrerede, hvordan man bygger JPA-projekt ved hjælp af Querydsl.

Det fuld implementering af denne artikel kan findes i github-projektet - dette er et Eclipse-baseret maven-projekt, så det skal være let at importere og køre som det er.

En hurtig note her er - kør en simpel maven-build (mvn ren installation) for at generere typerne i mål / genererede kilder - og derefter, hvis du bruger Eclipse - inkluder mappen som en kildemappe for projektet.