QueryDsl 避免多个 if 块

QueryDsl avoiding multiple if blocks

目前我在 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;
    ......
}

在我的服务中class我有这样的东西

 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 多个字段。所以我的服务 class 方法中有 10 个 If 块。有没有更好的方法可以避免这么多 if 块。

您可以使用 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;
}