Eine Anleitung zu Querydsl mit JPA

1. Übersicht

Querydsl ist ein umfangreiches Java-Framework, mit dem typsichere Abfragen in einer domänenspezifischen Sprache erstellt und ausgeführt werden können , die SQL ähnelt .

In diesem Artikel untersuchen wir Querydsl mit der Java Persistence API.

Eine kurze Randnotiz hier ist, dass HQL für Hibernate die erste Zielsprache für Querydsl war, aber heutzutage JPA, JDO, JDBC, Lucene, Hibernate Search, MongoDB, Sammlungen und RDFBean als Backends unterstützt.

2. Vorbereitungen

Fügen wir zunächst die erforderlichen Abhängigkeiten zu unserem Maven-Projekt hinzu:

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

Und jetzt konfigurieren wir das Maven APT-Plugin:

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

Der JPAAnnotationProcessor findet mit javax.persistence.Entity- Annotation kommentierte Domänentypen und generiert Abfragetypen für diese.

3. Abfragen mit Querydsl

Abfragen werden basierend auf generierten Abfragetypen erstellt, die die Eigenschaften Ihrer Domänentypen widerspiegeln. Auch Funktions- / Methodenaufrufe werden vollständig typsicher konstruiert.

Die Abfragepfade und -operationen sind in allen Implementierungen gleich, und auch die Abfrageschnittstellen verfügen über eine gemeinsame Basisschnittstelle.

3.1. Eine Entität und der Querydsl-Abfragetyp

Definieren wir zunächst eine einfache Entität, die wir verwenden werden, wenn wir Beispiele durchgehen:

@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 generiert einen Abfragetyp mit dem einfachen Namen QPerson im selben Paket wie Person . QPerson kann als statisch typisierte Variable in Querydsl-Abfragen als Repräsentant für den Personentyp verwendet werden.

Erstens - QPerson verfügt über eine Standardinstanzvariable, auf die als statisches Feld zugegriffen werden kann:

QPerson person = QPerson.person;

Alternativ können Sie Ihre eigenen Personenvariablen wie folgt definieren:

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

3.2. Abfrage mit JPAQuery erstellen

Wir können jetzt JPAQuery- Instanzen für unsere Abfragen verwenden:

JPAQuery query = new JPAQuery(entityManager);

Beachten Sie, dass der entityManager ein JPA EntityManager ist .

Lassen Sie uns nun alle Personen mit dem Vornamen „ Kent “ als schnelles Beispiel abrufen :

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

Der from- Aufruf definiert die Abfragequelle und -projektion, der where- Teil definiert den Filter und die Liste weist Querydsl an, alle übereinstimmenden Elemente zurückzugeben.

Wir können auch mehrere Filter verwenden:

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

Oder:

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

In nativer JPQL-Form würde die Abfrage folgendermaßen geschrieben:

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

Wenn Sie die Filter über "oder" kombinieren möchten, verwenden Sie das folgende Muster:

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

4. Bestellung und Aggregation in Querydsl

Lassen Sie uns nun einen Blick darauf werfen, wie Reihenfolge und Aggregation in der Querydsl-Bibliothek funktionieren.

4.1. Bestellung

Wir beginnen mit der Reihenfolge unserer Ergebnisse in absteigender Reihenfolge nach dem Nachnamenfeld :

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

4.2. Anhäufung

Verwenden wir jetzt eine einfache Aggregation, da einige verfügbar sind (Summe, Durchschnitt, Max, Min):

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

4.3. Aggregation mit GroupBy

Die Klasse com.mysema.query.group.GroupBy bietet Aggregationsfunktionen, mit denen wir Abfrageergebnisse im Speicher aggregieren können.

Hier ist ein kurzes Beispiel, in dem das Ergebnis als Map mit Vorname als Schlüssel und maximalem Alter als Wert zurückgegeben wird:

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

5. Testen mit Querydsl

Definieren wir nun eine DAO-Implementierung mit Querydsl - und definieren wir die folgende Suchoperation:

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); }

Lassen Sie uns nun einige Tests mit diesem neuen DAO erstellen und Querydsl verwenden, um nach neu erstellten Personenobjekten (implementiert in der PersonDao- Klasse) zu suchen, und in einer anderen Testaggregation mit der GroupBy- Klasse wird Folgendes getestet:

@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. Fazit

Dieses Tutorial zeigt, wie Sie ein JPA-Projekt mit Querydsl erstellen.

Die vollständige Implementierung dieses Artikels finden Sie im Github-Projekt. Dies ist ein Eclipse-basiertes Maven-Projekt. Daher sollte es einfach zu importieren und auszuführen sein.

Ein kurzer Hinweis hier ist: Führen Sie einen einfachen Maven-Build (mvn clean install) aus, um die Typen in Ziel- / generierten Quellen zu generieren. Wenn Sie Eclipse verwenden, fügen Sie den Ordner als Quellordner des Projekts hinzu.