QueryDsl避免多个if块

时间:2018-11-08 09:24:55

标签: java jpa java-8 querydsl

当前,我正在Java(带有JPA)EE项目中使用Query DSL。我从UI收到所有过滤器都为json的filterObject。我的FilterObject看起来像这样

public class FilterObject {

    private String name;
    private List<Status> status;
    private String module;
    private List<Source> source;
    ......
}

在我的服务班上,我有这样的事情

 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()));
        }
        ...............
        ...............
}

最后我有这个

JPAQuery<MyModel> query = new JPAQuery<>(getEntityManager());
List<MyModel> myModels =  query.from(QMyModel.mymodel).where(builder).fetch();

编辑:

/**
 * 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");

     ........
     .......
}

所有这些工作。但是我的FilterObject正在增长,并且具有10多个字段。所以我在服务类方法中有10个If块。有什么更好的方法可以避免很多if块。

1 个答案:

答案 0 :(得分:2)

您可以使用lambda,或者(在这种情况下甚至更好)方法参考

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;
}