QueryDsl avoiding multiple if blocks
up vote
2
down vote
favorite
Currently I am using Query DSL in my Java(with JPA) EE project. I recieve a filterObject from UI as json with all the filters. My FilterObject looks like this
public class FilterObject {
private String name;
private List<Status> status;
private String module;
private List<Source> source;
......
}
And in my service class I have something like this
public List<MyModel> findByFilter(FilterObject filterObject) {
BooleanBuilder builder = new BooleanBuilder();
QMyModel mymodel= QMyModel.myModel;
if(filterObject.getName() != null) {
builder.and(mymodel.name.contains(filterObject.getName()));
}
if(! CollectionUtils.isEmpty(filterObject.getStatus())) {
builder.and(mymodel.status.in(filterObject.getStatus()));
}
...............
...............
}
And finally I have this
JPAQuery<MyModel> query = new JPAQuery<>(getEntityManager());
List<MyModel> myModels = query.from(QMyModel.mymodel).where(builder).fetch();
EDIT:
/**
* QMyModel is a Querydsl query type for MyModel
*/
@Generated("com.querydsl.codegen.EntitySerializer")
public class QMyModel extends EntityPathBase<MyModel> {
private static final long serialVersionUID = 1041638507L;
private static final PathInits INITS = PathInits.DIRECT2;
public static final QMyModel myModel = new QMyModel("myModel");
public final StringPath name = createString("name");
public final EnumPath<Status> status = createEnum("status", Status.class);
public final StringPath module = createString("module");
........
.......
}
All these work. But my FilterObject is growing and has more than 10 fields. So I have like 10 If blocks in my service class method. Is there a better way to do this where I could avoid so many if blocks.
java jpa java-8 querydsl
add a comment |
up vote
2
down vote
favorite
Currently I am using Query DSL in my Java(with JPA) EE project. I recieve a filterObject from UI as json with all the filters. My FilterObject looks like this
public class FilterObject {
private String name;
private List<Status> status;
private String module;
private List<Source> source;
......
}
And in my service class I have something like this
public List<MyModel> findByFilter(FilterObject filterObject) {
BooleanBuilder builder = new BooleanBuilder();
QMyModel mymodel= QMyModel.myModel;
if(filterObject.getName() != null) {
builder.and(mymodel.name.contains(filterObject.getName()));
}
if(! CollectionUtils.isEmpty(filterObject.getStatus())) {
builder.and(mymodel.status.in(filterObject.getStatus()));
}
...............
...............
}
And finally I have this
JPAQuery<MyModel> query = new JPAQuery<>(getEntityManager());
List<MyModel> myModels = query.from(QMyModel.mymodel).where(builder).fetch();
EDIT:
/**
* QMyModel is a Querydsl query type for MyModel
*/
@Generated("com.querydsl.codegen.EntitySerializer")
public class QMyModel extends EntityPathBase<MyModel> {
private static final long serialVersionUID = 1041638507L;
private static final PathInits INITS = PathInits.DIRECT2;
public static final QMyModel myModel = new QMyModel("myModel");
public final StringPath name = createString("name");
public final EnumPath<Status> status = createEnum("status", Status.class);
public final StringPath module = createString("module");
........
.......
}
All these work. But my FilterObject is growing and has more than 10 fields. So I have like 10 If blocks in my service class method. Is there a better way to do this where I could avoid so many if blocks.
java jpa java-8 querydsl
There is support for auto-binding a predicate however you would need to switch to using a query string e.g. /orders?status=PAID&status=DELIVERED&customer.surname=smith. More details here: spring.io/blog/2015/09/04/…
– Alan Hay
Nov 8 at 9:36
@AlanHay thanks for the reply. I know aboutQueryDslPredicatebut that is in spring. But I am not using spring.
– pvpkiran
Nov 8 at 9:59
Can you post the classQMyModel?
– Benoit
Nov 8 at 10:22
@Benoit QMyModel is the autogenerated class of MyModel@Entityclass
– pvpkiran
Nov 8 at 11:06
1
You could possibly look at some kind of reflection based solution. Iterate the fields of the filter and return the corresponding boolean condition. You could use a custom annotation on the fields to allow for more flexible binding.
– Alan Hay
Nov 8 at 12:09
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
Currently I am using Query DSL in my Java(with JPA) EE project. I recieve a filterObject from UI as json with all the filters. My FilterObject looks like this
public class FilterObject {
private String name;
private List<Status> status;
private String module;
private List<Source> source;
......
}
And in my service class I have something like this
public List<MyModel> findByFilter(FilterObject filterObject) {
BooleanBuilder builder = new BooleanBuilder();
QMyModel mymodel= QMyModel.myModel;
if(filterObject.getName() != null) {
builder.and(mymodel.name.contains(filterObject.getName()));
}
if(! CollectionUtils.isEmpty(filterObject.getStatus())) {
builder.and(mymodel.status.in(filterObject.getStatus()));
}
...............
...............
}
And finally I have this
JPAQuery<MyModel> query = new JPAQuery<>(getEntityManager());
List<MyModel> myModels = query.from(QMyModel.mymodel).where(builder).fetch();
EDIT:
/**
* QMyModel is a Querydsl query type for MyModel
*/
@Generated("com.querydsl.codegen.EntitySerializer")
public class QMyModel extends EntityPathBase<MyModel> {
private static final long serialVersionUID = 1041638507L;
private static final PathInits INITS = PathInits.DIRECT2;
public static final QMyModel myModel = new QMyModel("myModel");
public final StringPath name = createString("name");
public final EnumPath<Status> status = createEnum("status", Status.class);
public final StringPath module = createString("module");
........
.......
}
All these work. But my FilterObject is growing and has more than 10 fields. So I have like 10 If blocks in my service class method. Is there a better way to do this where I could avoid so many if blocks.
java jpa java-8 querydsl
Currently I am using Query DSL in my Java(with JPA) EE project. I recieve a filterObject from UI as json with all the filters. My FilterObject looks like this
public class FilterObject {
private String name;
private List<Status> status;
private String module;
private List<Source> source;
......
}
And in my service class I have something like this
public List<MyModel> findByFilter(FilterObject filterObject) {
BooleanBuilder builder = new BooleanBuilder();
QMyModel mymodel= QMyModel.myModel;
if(filterObject.getName() != null) {
builder.and(mymodel.name.contains(filterObject.getName()));
}
if(! CollectionUtils.isEmpty(filterObject.getStatus())) {
builder.and(mymodel.status.in(filterObject.getStatus()));
}
...............
...............
}
And finally I have this
JPAQuery<MyModel> query = new JPAQuery<>(getEntityManager());
List<MyModel> myModels = query.from(QMyModel.mymodel).where(builder).fetch();
EDIT:
/**
* QMyModel is a Querydsl query type for MyModel
*/
@Generated("com.querydsl.codegen.EntitySerializer")
public class QMyModel extends EntityPathBase<MyModel> {
private static final long serialVersionUID = 1041638507L;
private static final PathInits INITS = PathInits.DIRECT2;
public static final QMyModel myModel = new QMyModel("myModel");
public final StringPath name = createString("name");
public final EnumPath<Status> status = createEnum("status", Status.class);
public final StringPath module = createString("module");
........
.......
}
All these work. But my FilterObject is growing and has more than 10 fields. So I have like 10 If blocks in my service class method. Is there a better way to do this where I could avoid so many if blocks.
java jpa java-8 querydsl
java jpa java-8 querydsl
edited Nov 8 at 18:04
Benoit
1,8031822
1,8031822
asked Nov 8 at 9:24
pvpkiran
11.2k42038
11.2k42038
There is support for auto-binding a predicate however you would need to switch to using a query string e.g. /orders?status=PAID&status=DELIVERED&customer.surname=smith. More details here: spring.io/blog/2015/09/04/…
– Alan Hay
Nov 8 at 9:36
@AlanHay thanks for the reply. I know aboutQueryDslPredicatebut that is in spring. But I am not using spring.
– pvpkiran
Nov 8 at 9:59
Can you post the classQMyModel?
– Benoit
Nov 8 at 10:22
@Benoit QMyModel is the autogenerated class of MyModel@Entityclass
– pvpkiran
Nov 8 at 11:06
1
You could possibly look at some kind of reflection based solution. Iterate the fields of the filter and return the corresponding boolean condition. You could use a custom annotation on the fields to allow for more flexible binding.
– Alan Hay
Nov 8 at 12:09
add a comment |
There is support for auto-binding a predicate however you would need to switch to using a query string e.g. /orders?status=PAID&status=DELIVERED&customer.surname=smith. More details here: spring.io/blog/2015/09/04/…
– Alan Hay
Nov 8 at 9:36
@AlanHay thanks for the reply. I know aboutQueryDslPredicatebut that is in spring. But I am not using spring.
– pvpkiran
Nov 8 at 9:59
Can you post the classQMyModel?
– Benoit
Nov 8 at 10:22
@Benoit QMyModel is the autogenerated class of MyModel@Entityclass
– pvpkiran
Nov 8 at 11:06
1
You could possibly look at some kind of reflection based solution. Iterate the fields of the filter and return the corresponding boolean condition. You could use a custom annotation on the fields to allow for more flexible binding.
– Alan Hay
Nov 8 at 12:09
There is support for auto-binding a predicate however you would need to switch to using a query string e.g. /orders?status=PAID&status=DELIVERED&customer.surname=smith. More details here: spring.io/blog/2015/09/04/…
– Alan Hay
Nov 8 at 9:36
There is support for auto-binding a predicate however you would need to switch to using a query string e.g. /orders?status=PAID&status=DELIVERED&customer.surname=smith. More details here: spring.io/blog/2015/09/04/…
– Alan Hay
Nov 8 at 9:36
@AlanHay thanks for the reply. I know about
QueryDslPredicate but that is in spring. But I am not using spring.– pvpkiran
Nov 8 at 9:59
@AlanHay thanks for the reply. I know about
QueryDslPredicate but that is in spring. But I am not using spring.– pvpkiran
Nov 8 at 9:59
Can you post the class
QMyModel ?– Benoit
Nov 8 at 10:22
Can you post the class
QMyModel ?– Benoit
Nov 8 at 10:22
@Benoit QMyModel is the autogenerated class of MyModel
@Entity class– pvpkiran
Nov 8 at 11:06
@Benoit QMyModel is the autogenerated class of MyModel
@Entity class– pvpkiran
Nov 8 at 11:06
1
1
You could possibly look at some kind of reflection based solution. Iterate the fields of the filter and return the corresponding boolean condition. You could use a custom annotation on the fields to allow for more flexible binding.
– Alan Hay
Nov 8 at 12:09
You could possibly look at some kind of reflection based solution. Iterate the fields of the filter and return the corresponding boolean condition. You could use a custom annotation on the fields to allow for more flexible binding.
– Alan Hay
Nov 8 at 12:09
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
You can use lambda's, or (even better in this case) method reference:
public List<MyModel> findByFilter(FilterObject filterObject) {
BooleanBuilder builder = new BooleanBuilder();
QMyModel mymodel = QMyModel.myModel;
add(builder, filterObject.getName(), mymodel.name::contains);
add(builder, filterObject.getStatus(), mymodel.status::in);
...
}
private <T> void add(BooleanBuilder builder, T filterElement, Function<T, BooleanExpression> booleanExpressionFunction) {
if (valid(filterElement)) {
builder.and(booleanExpressionFunction.apply(filterElement));
}
}
private boolean valid(Object filterElement) {
if (filterElement == null) {
return false;
}
if (filterElement instanceof Collection) {
return !((Collection) filterElement).isEmpty();
}
return true;
}
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
You can use lambda's, or (even better in this case) method reference:
public List<MyModel> findByFilter(FilterObject filterObject) {
BooleanBuilder builder = new BooleanBuilder();
QMyModel mymodel = QMyModel.myModel;
add(builder, filterObject.getName(), mymodel.name::contains);
add(builder, filterObject.getStatus(), mymodel.status::in);
...
}
private <T> void add(BooleanBuilder builder, T filterElement, Function<T, BooleanExpression> booleanExpressionFunction) {
if (valid(filterElement)) {
builder.and(booleanExpressionFunction.apply(filterElement));
}
}
private boolean valid(Object filterElement) {
if (filterElement == null) {
return false;
}
if (filterElement instanceof Collection) {
return !((Collection) filterElement).isEmpty();
}
return true;
}
add a comment |
up vote
2
down vote
accepted
You can use lambda's, or (even better in this case) method reference:
public List<MyModel> findByFilter(FilterObject filterObject) {
BooleanBuilder builder = new BooleanBuilder();
QMyModel mymodel = QMyModel.myModel;
add(builder, filterObject.getName(), mymodel.name::contains);
add(builder, filterObject.getStatus(), mymodel.status::in);
...
}
private <T> void add(BooleanBuilder builder, T filterElement, Function<T, BooleanExpression> booleanExpressionFunction) {
if (valid(filterElement)) {
builder.and(booleanExpressionFunction.apply(filterElement));
}
}
private boolean valid(Object filterElement) {
if (filterElement == null) {
return false;
}
if (filterElement instanceof Collection) {
return !((Collection) filterElement).isEmpty();
}
return true;
}
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
You can use lambda's, or (even better in this case) method reference:
public List<MyModel> findByFilter(FilterObject filterObject) {
BooleanBuilder builder = new BooleanBuilder();
QMyModel mymodel = QMyModel.myModel;
add(builder, filterObject.getName(), mymodel.name::contains);
add(builder, filterObject.getStatus(), mymodel.status::in);
...
}
private <T> void add(BooleanBuilder builder, T filterElement, Function<T, BooleanExpression> booleanExpressionFunction) {
if (valid(filterElement)) {
builder.and(booleanExpressionFunction.apply(filterElement));
}
}
private boolean valid(Object filterElement) {
if (filterElement == null) {
return false;
}
if (filterElement instanceof Collection) {
return !((Collection) filterElement).isEmpty();
}
return true;
}
You can use lambda's, or (even better in this case) method reference:
public List<MyModel> findByFilter(FilterObject filterObject) {
BooleanBuilder builder = new BooleanBuilder();
QMyModel mymodel = QMyModel.myModel;
add(builder, filterObject.getName(), mymodel.name::contains);
add(builder, filterObject.getStatus(), mymodel.status::in);
...
}
private <T> void add(BooleanBuilder builder, T filterElement, Function<T, BooleanExpression> booleanExpressionFunction) {
if (valid(filterElement)) {
builder.and(booleanExpressionFunction.apply(filterElement));
}
}
private boolean valid(Object filterElement) {
if (filterElement == null) {
return false;
}
if (filterElement instanceof Collection) {
return !((Collection) filterElement).isEmpty();
}
return true;
}
answered Nov 8 at 12:06
Benoit
1,8031822
1,8031822
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53204767%2fquerydsl-avoiding-multiple-if-blocks%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
There is support for auto-binding a predicate however you would need to switch to using a query string e.g. /orders?status=PAID&status=DELIVERED&customer.surname=smith. More details here: spring.io/blog/2015/09/04/…
– Alan Hay
Nov 8 at 9:36
@AlanHay thanks for the reply. I know about
QueryDslPredicatebut that is in spring. But I am not using spring.– pvpkiran
Nov 8 at 9:59
Can you post the class
QMyModel?– Benoit
Nov 8 at 10:22
@Benoit QMyModel is the autogenerated class of MyModel
@Entityclass– pvpkiran
Nov 8 at 11:06
1
You could possibly look at some kind of reflection based solution. Iterate the fields of the filter and return the corresponding boolean condition. You could use a custom annotation on the fields to allow for more flexible binding.
– Alan Hay
Nov 8 at 12:09