I am building a dynamic query using a FilfetDto If the user has filled some field in the UI, th e contains some values but not all. So i have to test each property to construct a query filtering only on filled (not empty) field :
JPAQuery dslQuery = new JPAQuery(em);
dslQuery.from(book);
dslQuery.join(book.author, author);
String title = StringUtils.upperCase(StringUtils.trim(_filter.getTitle()));
if (StringUtils.isNotBlank(title)) {
dslQuery.where(book.title.upper().like(title));
}
String isbn = StringUtils.trim(_filter.getIsbn());
if (StringUtils.isNotBlank(isbn)) {
dslQuery.where(book.isbn.like(isbn));
}
if (_filter.getAuthorId() != null) {
dslQuery.where(author.id.eq(_filter.getAuthorId()));
}
Is there a way to abstract the "if" with another more readable syntax ?
I would like something like :
JPAQuery dslQuery = new JPAQuery(em);
dslQuery.from(book);
dslQuery.join(book.author, author);
dslQuery.where(book.title.upperIfNotBlank().like(title));
dslQuery.where(book.isbn.likeIfNotNull(isbn));
dslQuery.where(author.id.eqIfNotNull(_filter.getAuthorId()));
It would be nice if the "IfNotNull" could be turned on, or even be the default behaviour ...
so it would end up like this :
dslQuery.where(book.title.upper().like(title));
dslQuery.where(book.isbn.like(isbn));
dslQuery.where(author.id.eq(_filter.getAuthorId()));
Is there a way to abstract the "if" with another more readable syntax ?
No, and probably there won't be. The aim of Querydsl expressions is to stay as close to the form that is used by the underlying persistence technology.
If you want to use such an approach in your own project feel free to put this into your own subclass of AbstractJPAQuery. Querydsl queries are meant to be customized for such cases.
I create a QueryDSLHelper class which has static methods which do the null check before adding the expression. Something like this:
public static void goe(BooleanBuilder builder, DateTimePath<Date> path, Date value) {
if(date!=null) {
builder.and(path.goe(value));
}
}
public static void like(BooleanBuilder builder, StringPath path, String value) {
if(value!=null) {
builder.and(path.like(value));
}
}
Now I can just statically import those methods and call them on one line:
like(builder, book.isbn, isbn);
This is extremely useful and very clean/readable when implementing 'filter' or 'filterByExample' queries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With