Querying Collections
The querydsl-collections module can be used with generated query types or
without. The first section describes usage without generated query types.
Usage Without Generated Query Types
To use querydsl-collections without generated query types, use the Querydsl
alias feature.
Add the following static imports:
// needed for access of the Querydsl Collections API
import static com.querydsl.collections.CollQueryFactory.*;
// needed if you use the $-invocations
import static com.querydsl.core.alias.Alias.*;
Create an alias instance for the Cat class. Alias instances can only be
created for non-final classes with an empty constructor.
The alias instance and its getter invocations are transformed into paths by
wrapping them in dollar-method invocations. The call c.getKittens() is
internally transformed into the property path c.kittens inside the dollar
method.
Cat c = alias(Cat.class, "cat");
for (String name : select($(c.getName())).from($(c),cats)
.where($(c.getKittens()).size().gt(0))
.fetch()) {
System.out.println(name);
}
The following example is a variation where the access to the list size happens inside the dollar-method invocation:
Cat c = alias(Cat.class, "cat");
for (String name : select($(c.getName())).from($(c),cats)
.where($(c.getKittens().size()).gt(0))
.fetch()) {
System.out.println(name);
}
All non-primitive and non-final typed properties of aliases are aliases themselves. You may cascade method calls until you hit a primitive or final type in the dollar-method scope, e.g.:
$(c.getMate().getName())
is transformed into c.mate.name internally, but:
$(c.getMate().getName().toLowerCase())
is not transformed properly, since the toLowerCase() invocation is not
tracked.
You may only invoke getters, size(), contains(Object), and get(int) on
alias types. All other invocations throw exceptions.
Usage With Generated Query Types
The same query expressed with generated expression types:
QCat cat = new QCat("cat");
for (String name : select(cat.name).from(cat,cats)
.where(cat.kittens.size().gt(0))
.fetch()) {
System.out.println(name);
}
When you use generated query types, you instantiate expressions instead of alias instances and use the property paths directly without any dollar-method wrapping.
Maven Integration
Add the following dependencies to your Maven project:
<dependency>
<groupId>io.github.openfeign.querydsl</groupId>
<artifactId>querydsl-collections</artifactId>
<version>7.1</version>
</dependency>
If you are not using JPA you can generate expression types for your domain
types by annotating them with com.querydsl.core.annotations.QueryEntity and
configuring the maven-compiler-plugin:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<generatedSourcesDirectory>target/generated-sources/java</generatedSourcesDirectory>
</configuration>
<dependencies>
<dependency>
<groupId>io.github.openfeign.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>7.1</version>
<classifier>general</classifier>
</dependency>
</dependencies>
</plugin>
Hamcrest Matchers
Querydsl Collections provides Hamcrest matchers:
import static org.hamcrest.core.IsEqual.equalTo;
import static com.querydsl.collections.PathMatcher.hasValue;
import static org.junit.Assert.assertThat;
Car car = new Car();
car.setHorsePower(123);
assertThat(car, hasValue($.horsePower));
assertThat(car, hasValue($.horsePower, equalTo(123)));
Usage With the Eclipse Compiler for Java
If querydsl-collections is used with a JRE where the system compiler is not
available, CollQuery instances can be configured to use the Eclipse Compiler
for Java (ECJ) instead:
DefaultEvaluatorFactory evaluatorFactory = new DefaultEvaluatorFactory(
CollQueryTemplates.DEFAULT,
new ECJEvaluatorFactory(getClass().getClassLoader()));
QueryEngine queryEngine = new DefaultQueryEngine(evaluatorFactory);
CollQuery query = new CollQuery(queryEngine);