QueryDSL vorgestellt

Eine meiner absoluten Lieblings-Bibliotheken beim Arbeiten mit relationalen Datenbanken in Java ist Query-DSL. Das schreiben von typesafe queries mit JPA war noch nie so einfach und bequem. Trotzdem ist meine Erfahrung, dass die Lib in vielen Projektteams nicht eingesetzt wird bzw. unbekannt ist. Deswegen hier eine kurze Vorstellung

Offizielle Website

Einbinden ins Projekt

Mit Maven:

<!-- https://mvnrepository.com/artifact/com.querydsl/querydsl-core -->
<dependency>
     <groupId>com.querydsl</groupId>
     <artifactId>querydsl-core</artifactId>
     <version>${querydsl.version}</version>
</dependency>
<dependency>
     <groupId>com.querydsl</groupId>
     <artifactId>querydsl-jpa</artifactId>
     <version>${querydsl.version}</version>
     <classifier>jakarta</classifier>
</dependency>

Funktionsweise

QueryDSL generiert ein Meta-Model deiner Entity-Klassen im Projekt mit denen du im Anschluss deine Queries schreiben kannst.
Das Generieren der Meta-Klassen (mit Q Prefix) übernimmt ein Maven Plugin:

<plugin>
     <groupId>com.mysema.maven</groupId>
         <artifactId>apt-maven-plugin</artifactId>
         <version>1.1.3</version>
         <executions>
             <execution>
                  <goals>
                      <goal>process</goal>
                   </goals>
                   <configuration>
                       <outputDirectory>target/generated-sources/java</outputDirectory>
                          <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                   </configuration>
                    </execution>
         </executions>
         <dependencies>
              <dependency>
                  <groupId>com.querydsl</groupId>
                  <artifactId>querydsl-apt</artifactId>
                  <version>${querydsl.version}</version>
                  <classifier>jakarta</classifier>
              </dependency>
          </dependencies>
</plugin>

Der Folder der hier als outputDirectory gewählt wird sollte in der IDE auch als Source Folder markiert werden damit alles kompiliert.

Verwendung

Sobald die Dependencies im Projekt sind und einmal mit mvn generate-sources gebuildet wurde kann QueryDSL schon verwendet werden:

public List<KmUser> findMembersOfOrgsWithRoles(List<Long> orgIds, List<KmSystemRole> roles) {
        
JPAQuery<KmUser> query = new JPAQuery<>(entityManager);
QKmUser qKmUser = QKmUser.kmUser;
QMember qMember = QMember.member;
QOrg qOrg = QOrg.org;


return query.from(qKmUser)
                .join(qMember).on(qKmUser.id.eq(qMember.kmUserId))
                .join(qOrg).on(qMember.orgId.eq(qOrg.id))
                .where((qOrg.id.in(orgIds))
                   .and(qMember.roleId.in(roles.stream().map(r -> r.getId())
.collect(Collectors.toList())))
.and(qMember.statusId.eq(MemberStatus.APPROVED.getId()))).distinct().fetch();

}

Unter Verwendung der generierten Meta-Klassen können nun Queries in nahezu bekannter SQL Schreibweise formuliert werden. Das ganze ist natürlich Type-Safe und verbessert die Lesbarkeit vor allem wenn die Query dynamisch konfiguriert wird:

 if(!CollectionUtils.isEmpty(statusList)) {
            if(statusList.size() == 1) {
                query.where(qMember.statusId.eq(statusList.get(0).getId()));
            }
            else {
                query.where(qMember.statusId.in(statusList.stream().map(s -> s.getId()).collect(Collectors.toList())));
            }
}

Falls du in deinem Projekt eine relationale Datenbank mit JPA im Einsatz hast ist QueryDSL definitiv eine wertvolle Ergänzung im die Lesbarkeit und Wartbarkeit deiner dynamischen Queries zu verbessern.

Weiterführend

Baeldung Artikel – mit einer etwas detaillierteren Intro

Reference Doku


Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert