Juery is a tiny Java library to manage search and filter query from user to database. api and basic packages have no dependencies. They contain everything you need to use Juery. The jooq package contains useful tools for projects using the jOOQ DSL.
Use the package manager maven to install juery.
<dependency>
<groupId>fr.ght1pc9kc</groupId>
<artifactId>juery-api</artifactId>
<version>VERSION</version>
</dependency>
<dependency>
<groupId>fr.ght1pc9kc</groupId>
<artifactId>juery-basic</artifactId>
<version>VERSION</version>
</dependency>
<dependency>
<groupId>fr.ght1pc9kc</groupId>
<artifactId>juery-jooq</artifactId>
<version>VERSION</version>
</dependency>for gradle
compile "fr.ght1pc9kc:juery-api:VERSION"
compile "fr.ght1pc9kc:juery-basic:VERSION"
compile "fr.ght1pc9kc:juery-jooq:VERSION"import fr.ght1pc9kc.juery.api.Criteria;
Criteria.property("jedi").eq("Obiwan")
.and(Criteria.property("age").gt(40)
.or(Criteria.property("age").lt(20)));import fr.ght1pc9kc.juery.api.PageRequest;
import fr.ght1pc9kc.juery.api.pagination.Direction;
import fr.ght1pc9kc.juery.api.pagination.Order;
import fr.ght1pc9kc.juery.api.pagination.Sort;
PageRequest.builder()
.page(2).size(100)
.filter(Criteria.property("profile").eq("jedi").and(Criteria.property("job").eq("master")))
.sort(Sort.of(new Order(Direction.ASC, "name"), new Order(Direction.DESC, "email")))
.build();Into the controller.
import fr.ght1pc9kc.juery.basic.QueryStringParser;
@GetMapping
public Flux<Feed> list(@RequestParam Map<String, String> queryStringParams) {
return feedService.list(QueryStringParser.withDefaultConfig().parse(queryStringParams))
.onErrorMap(BadCriteriaFilter.class, e -> new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getLocalizedMessage()));
}QueryStringParser will transform the query string into a PageRequest which contains a Criteria.
Depending on your architecture, the object will traverse layers until persistence.
It can be enriched in the process by with methods which create a new enriched object. All the API is strictly immutable.
Since 1.2.0: You can now, configure the QueryStringParser to customize the querystring parameters used :
import fr.ght1pc9kc.juery.basic.ParserConfiguration;
ParserConfiguration config = ParserConfiguration.builder()
.page("_pg")
.size("_sz")
.from("_fr")
.to("_to")
.sort("_st")
.maxPageSize(20)
.build();
QueryStringParser.withConfig(config).parse(queryStringParams);In the persistence layer we will be able to use Visitors as follows.
import fr.ght1pc9kc.juery.jooq.filter.JooqConditionVisitor;
private static final JooqConditionVisitor JOOQ_CONDITION_VISITOR =
new JooqConditionVisitor(PropertiesMappers.FEEDS_PROPERTIES_MAPPING::get);The JooqConditionVisitor implementation takes as input a Function <String, Field <?>> which will allow to transform
the properties of your criteria, into jOOQ Field objects corresponding to columns of your tables.
import fr.ght1pc9kc.juery.api.Criteria;
import fr.ght1pc9kc.juery.api.PageRequest;
// transforms the Criteria present in pageRequest into Condition
Condition conditions = pageRequest.filter.visit(JOOQ_CONDITION_VISITOR);
// Execute query with the conditions generated by the visitor
Cursor<Record> cursor = dsl
.select(FEEDS.fields()).select(FEEDS_USERS.FEUS_TAGS)
.from(FEEDS)
.leftJoin(FEEDS_USERS).on(FEEDS_USERS.FEUS_FEED_ID.eq(FEEDS.FEED_ID))
.where(conditions).fetchLazy();The PageRequest object contains the data necessary for pagination. You can implement it yourself,
but for jOOQ users, the JooqPagination helper makes it easier.
import fr.ght1pc9kc.juery.api.Criteria;
import fr.ght1pc9kc.juery.api.PageRequest;
// transforms the Criteria present in pageRequest into Condition
Condition conditions = pageRequest.filter.visit(NEWS_CONDITION_VISITOR);
// Apply pagination parameters to the query
final Select<Record> query = JooqPagination.apply(pageRequest, PropertiesMappers.FEEDS_PROPERTIES_MAPPING, dsl
.select(FEEDS.fields()).select(FEEDS_USERS.FEUS_TAGS)
.from(FEEDS)
.leftJoin(FEEDS_USERS).on(FEEDS_USERS.FEUS_FEED_ID.eq(FEEDS.FEED_ID))
.where(conditions)
);
Cursor<Record> cursor = query.fetchLazy();We find the PropertiesMappers.FEEDS_PROPERTIES_MAPPING, optional, which allows to make the link between the sort
criteria and the table fields.
As an example to illustrate what is PropertiesMappers.FEEDS_PROPERTIES_MAPPING in the context of using jOOQ as DSL.
public static final Map<String, Field<?>> FEEDS_PROPERTIES_MAPPING = Map.of(
"id", FEEDS.FEED_ID,
"name", FEEDS.FEED_NAME,
...
);FEEDS was a jOOQ Table generated before compilation with jooq-codegen-maven Maven Plugin. "id" and "name" was properties
used in Criteria.
import fr.ght1pc9kc.juery.api.Criteria;
Criteria.property("id").eq("F0042")
.and(Criteria.property("name").eq("H2G2"));Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.