From bc167fbad0e95911b4bd268a3091ccb7da319662 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 5 Mar 2025 11:15:46 +0100 Subject: [PATCH] Refine Querydsl documentation. Closes #538 --- pom.xml | 2 +- src/main/antora/modules/ROOT/nav.adoc | 1 - .../pages/repositories/core-extensions.adoc | 176 +++++++++++++++++- 3 files changed, 176 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index fc477fa..b1fd6e8 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ com.querydsl - querydsl-mongodb + querydsl-core ${querydsl} true diff --git a/src/main/antora/modules/ROOT/nav.adoc b/src/main/antora/modules/ROOT/nav.adoc index edb3d96..2a68294 100644 --- a/src/main/antora/modules/ROOT/nav.adoc +++ b/src/main/antora/modules/ROOT/nav.adoc @@ -17,7 +17,6 @@ ** xref:ldap/configuration.adoc[] ** xref:ldap/usage.adoc[] ** xref:ldap/query-methods.adoc[] -** xref:ldap/querydsl.adoc[] ** xref:ldap/cdi-integration.adoc[] * xref:attachment$api/java/index.html[Javadoc,role=link-external,window=_blank] diff --git a/src/main/antora/modules/ROOT/pages/repositories/core-extensions.adoc b/src/main/antora/modules/ROOT/pages/repositories/core-extensions.adoc index a7c2ff8..d9662ef 100644 --- a/src/main/antora/modules/ROOT/pages/repositories/core-extensions.adoc +++ b/src/main/antora/modules/ROOT/pages/repositories/core-extensions.adoc @@ -1 +1,175 @@ -include::{commons}@data-commons::page$repositories/core-extensions.adoc[] +[[core.extensions]] += Spring Data Extensions + +This section documents a set of Spring Data extensions that enable Spring Data usage in a variety of contexts. +Currently, most of the integration is targeted towards Spring MVC. + +include::{commons}@data-commons::page$repositories/core-extensions-querydsl.adoc[leveloffset=1] + +[[ldap.repositories.queries.type-safe]] +=== Type-safe Query Methods with Querydsl + +LDAP repository counterpart integrates with the http://www.querydsl.com/[Querydsl] project, which provides a way to perform type-safe queries. + +[quote,Querydsl Team] +Instead of writing queries as inline strings or externalizing them into XML files they are constructed via a fluent API. + +It provides the following features: + +* Code completion in the IDE (all properties, methods, and operations can be expanded in your favorite Java IDE). +* Almost no syntactically invalid queries allowed (type-safe on all levels). +* Domain types and properties can be referenced safely -- no strings involved! +* Adapts better to refactoring changes in domain types. +* Incremental query definition is easier. + +See the http://www.querydsl.com/static/querydsl/latest/reference/html/[Querydsl documentation] for how to bootstrap your environment for APT-based code generation using Maven or Ant. + +Querydsl lets you write queries such as the following: + +==== +[source,java,indent=0,subs="verbatim,quotes",role="primary"] +---- +QPerson person = QPerson.person; +List result = repository.findAll(person.address.zipCode.eq("C0123")); + +Page page = repository.findAll(person.lastname.contains("a"), + PageRequest.of(0, 2, Direction.ASC, "lastname")); +---- +==== + +`QPerson` is a class that is generated by the Java annotation processor. +See xref:#ldap.repositories.queries.type-safe.apt[Setting up Annotation Processing] for how to set up Annotation Processing with your Build System. +It is a `Predicate` that lets you write type-safe queries. +Notice that there are no strings in the query other than the `C0123` value. + +You can use the generated `Predicate` class by using the `QuerydslPredicateExecutor` interface, which the following listing shows: + +==== +[source,java,indent=0,subs="verbatim,quotes",role="primary"] +---- +public interface QuerydslPredicateExecutor { + + Optional findOne(Predicate predicate); + + List findAll(Predicate predicate); + + List findAll(Predicate predicate, Sort sort); + + List findAll(Predicate predicate, OrderSpecifier... orders); + + Page findAll(Predicate predicate, Pageable pageable); + + List findAll(OrderSpecifier... orders); + + long count(Predicate predicate); + + boolean exists(Predicate predicate); + + R findBy(Predicate predicate, Function, R> queryFunction); +} +---- +==== + +To use this in your repository implementation, add it to the list of repository interfaces from which your interface inherits, as the following example shows: + +==== +[source,java,indent=0,subs="verbatim,quotes",role="primary"] +---- +interface PersonRepository extends LdapRepository, QuerydslPredicateExecutor { + + // additional query methods go here +} +---- +==== + +[[ldap.repositories.queries.type-safe.apt]] +=== Setting up Annotation Processing + +To use Querydsl with Spring Data LDAP, you need to set up annotation processing in your build system that generates the `Q` classes. +While you could write the `Q` classes by hand, it is recommended to use the Querydsl annotation processor to generate them for you to keep your `Q` classes in sync with your domain model. + +Spring Data LDAP ships with an annotation processor javadoc:org.springframework.data.ldap.repository.support.LdapAnnotationProcessor[] that isn't registered by default. +Typically, annotation processors are registered through Java's service loader via `META-INF/services/javax.annotation.processing.Processor` that also activates these once you have them on the class path. +Most Spring Data users do not use Querydsl, so it does not make sense to require additional mandatory dependencies for projects that would not benefit from Querydsl. +Hence, you need to activate annotation processing in your build system. + +The following example shows how to set up annotation processing by mentioning dependencies and compiler config changes in Maven and Gradle: + +[tabs] +====== +Maven:: ++ +[source,xml,indent=0,subs="verbatim,quotes",role="primary"] +---- + + + org.springframework.data + spring-data-ldap + + + + com.querydsl + querydsl-core + ${querydslVersion} + jakarta + + + + com.querydsl + querydsl-apt + ${querydslVersion} + jakarta + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.springframework.data.ldap.repository.support.LdapAnnotationProcessor + + + + + target/generated-test-sources + target/generated-sources + + + + +---- + +Gradle:: ++ +==== +[source,groovy,indent=0,subs="verbatim,quotes",role="secondary"] +---- +dependencies { + implementation 'com.querydsl:querydsl-core:${querydslVersion}:jakarta' + + annotationProcessor 'com.querydsl:querydsl-apt:${querydslVersion}:jakarta' + annotationProcessor 'org.springframework.data:spring-data-ldap' + + testAnnotationProcessor 'com.querydsl:querydsl-apt:${querydslVersion}:jakarta' + testAnnotationProcessor 'org.springframework.data:spring-data-ldap' +} + +tasks.withType(JavaCompile).configureEach { + options.compilerArgs += [ + "-processor", + "org.springframework.data.ldap.repository.support.LdapAnnotationProcessor"] +} +---- +==== +====== + +Note that the setup above shows the simplest usage omitting any other options or dependencies that your project might require. + +include::{commons}@data-commons::page$repositories/core-extensions-web.adoc[leveloffset=1] + +include::{commons}@data-commons::page$repositories/core-extensions-populators.adoc[leveloffset=1]