QueryDsl избегая нескольких блоков if - PullRequest
0 голосов
/ 08 ноября 2018

В настоящее время я использую Query DSL в своем проекте EE на Java (с JPA). Я получаю filterObject из пользовательского интерфейса как json со всеми фильтрами. Мой 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();

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

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

Все это работает. Но мой FilterObject растет и имеет более 10 полей. Таким образом, у меня есть 10 блоков If в моем методе класса обслуживания. Есть ли лучший способ сделать это, где я мог бы избежать так много блоков if.

1 Ответ

0 голосов
/ 08 ноября 2018

Вы можете использовать лямбда, или (еще лучше в этом случае) справочник по методам :

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