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.