The querydsl-collections module can be used with generated query types and without. The first section describes the usage without generated query types:
To use querydsl-collections without generated query types you need to use the Querydsl alias feature. Here are some examples.
To get started, 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.*;
And now create an alias instance for the Cat class. Alias instances can only be created for non-final classes with an empty constructor. Make sure your class has one.
The alias instance of type Cat and its getter invocations are
transformed into paths by wrapping them into dollar method invocations.
The call
c.getKittens()
for example 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 of the previous, 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. So you may cascade method calls until you hit a primitive or non-final type (e.g. java.lang.String) 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.
Note also that you may only invoke getters, size(), contains(Object) and get(int) on alias types. All other invocations throw exceptions.
The example above can be expressed like this 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.
Add the following dependencies to your Maven project:
<dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>${querydsl.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-collections</artifactId> <version>${querydsl.version}</version> </dependency>
If you are not using JPA or JDO you can generate expression types for your
domain types by
annotating them with the
com.querydsl.core.annotations.QueryEntity
annotation and adding the
following plugin configuration into your Maven configuration (pom.xml):
<project> <build> <plugins> ... <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.QuerydslAnnotationProcessor</processor> </configuration> </execution> </executions> </plugin> ... </plugins> </build> </project>
Place the jar files from the full-deps bundle on your classpath and use the following tasks for Querydsl code generation:
<!-- APT based code generation --> <javac srcdir="${src}" classpathref="cp"> <compilerarg value="-proc:only"/> <compilerarg value="-processor"/> <compilerarg value="com.querydsl.apt.QuerydslAnnotationProcessor"/> <compilerarg value="-s"/> <compilerarg value="${generated}"/> </javac> <!-- compilation --> <javac classpathref="cp" destdir="${build}"> <src path="${src}"/> <src path="${generated}"/> </javac>
Replace src with your main source folder, generated with your folder for generated sources and build with your target folder.
Querydsl Collections provides Hamcrest matchers. With these imports
import static org.hamcrest.core.IsEqual.equalTo; import static com.querydsl.collections.PathMatcher.hasValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat;
they can be used like this:
Car car = new Car(); car.setHorsePower(123); assertThat(car, hasValue($.horsePower)); assertThat(car, hasValue($.horsePower, equalTo(123)));
The Hamcrest matchers have been contributed by Jeroen van Schagen .
If Querydsl Collections is used with a JRE where the system compiler is not available, CollQuery instances can also 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);