This is a Spring Boot + MongoDB comparison between Querydsl and MongoTemplate:
A MongoDB or Docker to run it from an image, Maven
If you don't have a MongoDB running, the app work well with a Docker container:
docker run --name mymongo -d mongo:jessie
Once started, the application will create a database called "data" and a collection called bestPracticesDocument containing 10 records.
To compile and start the app (Uses port 8090 and try to connect to MongoDB on the default port (27017):
mvn spring-boot:run
Once started you can try the api using curl or Postman as following (Querydsl):
localhost:8090/api/v1/bestpractices/documents/?description=bp
localhost:8090/api/v1/bestpractices/documents/?description=bp&phase=6
localhost:8090/api/v1/bestpractices/documents/?description=bp&phase=bp&size=3&page=2
Or that version with (MongoTemplate):
localhost:8090/api/v1/bestpractices/documents/search?description=bp
localhost:8090/api/v1/bestpractices/documents/search?description=bp&phase=6
localhost:8090/api/v1/bestpractices/documents/search?description=bp&phase=bp&size=3&page=2
localhost:8090/api/v1/bestpractices/documents/search?categories=cat0
The following maven plugin is generating Query type objects from the @Document entity:
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>${apt.version}</version>
<dependencies>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>src/main/java/generated-sources/queries</outputDirectory>
<processor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor</processor>
<logOnlyOnError>true</logOnlyOnError>
</configuration>
</execution>
</executions>
</plugin>
The repository interface extends from QuerydslPredicateExecutor
which is typed with the "Query type" object that was generated by the MongoAnnotationProcessor (see above). When a REST call is done the MongoDB implementation of QuerydslPredicateExecutor
: QuerydslMongoPredicateExecutor
is using the generated Predicate
from the request to query the DB.
The repository interface:
public interface BestPracticesRepository
extends CrudRepository<BestPracticesDocument, String>, QuerydslPredicateExecutor<BestPracticesDocument>, QuerydslBinderCustomizer<com.example.pocQuerydsl.BestPractices.QBestPracticesDocument> {
/*
* (non-Javadoc)
* @see org.springframework.data.querydsl.binding.QuerydslBinderCustomizer#customize(org.springframework.data.querydsl.binding.QuerydslBindings, com.mysema.query.types.EntityPath)
*/
@Override
default public void customize(QuerydslBindings bindings, com.example.pocQuerydsl.BestPractices.QBestPracticesDocument doc) {
bindings.bind(String.class).first((StringPath path, String value) -> path.containsIgnoreCase(value));
//bindings.excluding(doc.id);
}
}
The REST controller:
@GetMapping(value = "/documents", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<BestPracticesDocument>> getDocument(@QuerydslPredicate(root = BestPracticesDocument.class) Predicate predicate, //
@PageableDefault(sort = { "description", "phase" }) Pageable pageable, //
@RequestParam MultiValueMap<String, String> parameters){
return new ResponseEntity<>(repository.findAll(predicate, pageable).stream().collect(Collectors.toList()), HttpStatus.OK);
}