返回一个计算结果为true的QueryDSL BooleanExpression

时间:2012-09-05 15:43:00

标签: null querydsl

假设我有CustomerQueryInfo bean,其中包含以下属性:

  • String firstName
  • String lastName
  • StatusEnum状态

我想使用此类型的对象执行“ QueryDSL ”搜索,该对象将返回客户列表List<Customer>

如果CustomerQueryInfo的某个字段是null,我不想在搜索中使用它。因此,将所有三个字段设置为CustomerQueryInfo null对象将返回所有客户

我正在寻找使用QueryDSL执行此类搜索的最佳做法。

是这样的:

private BooleanExpression isFirstNameLike(String firstName){
    if(firstName==null)
        return true BooleanExpression somehow;
    return QCustomer.customer.firstName.like(firstName);
}

private BooleanExpression isStatutEq(StatusEnum status){
    if(status==null)
        return true BooleanExpression somehow;
    return QCustomer.customer.status.eq(status);
}

然后:

return query.from(customer).where(isFirstNameLike(customerQueryInfo.getFirstName).and(isLastNameLike(customerQueryInfo.getLastName).and(isStatusEq(customerQueryInfo.getStatus))).list;
  1. 如何返回评估为true的BooleanExpression
  2. 如果不建议采用上述方法,那么建议的最佳做法是什么?

5 个答案:

答案 0 :(得分:18)

  

如何返回计算结果为true的BooleanExpression?

BooleanExpression alwaysTrue = Expressions.asBoolean(true).isTrue();

答案 1 :(得分:17)

您可以安全地使用像这样的空谓词

private BooleanExpression isFirstNameLike(String firstName){
    return firstName != null ? customer.firstName.like(firstName) : null;        
}

private BooleanExpression isStatusEq(StatusEnum status){
    return status != null ? customer.status.eq(status) : null;
}

并使用其中的varargs方面

query.from(customer)
     .where(
         isFirstNameLike(customerQueryInfo.getFirstName()),
         isLastNameLike(customerQueryInfo.getLastName()),
         isStatusEq(customerQueryInfo.getStatus()))
     .list(customer);

答案 2 :(得分:7)

使用java 8和BooleanBuilder,您可以实现这样的优雅方式:

Java 8 Optional&amp; LAMBDA

public final class ProductQuery {
    public static BooleanExpression nameEqualTo(String name){
        return ofNullable(name).map(QProduct.product.name::eq).orElse(null);
    }
}

BooleanBuilder

BooleanBuilder where = new BooleanBuilder()
    .and(ProductQuery.nameEqualTo(name));

答案 3 :(得分:5)

我创建了一个QueryDSLHelper类,它具有静态方法,在添加表达式之前进行空值检查。像这样:

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

现在我可以静态导入这些方法并在一行上调用它们:

        like(builder, book.isbn, isbn);

这在实施“过滤器”时非常有用且非常干净/可读。或者&#39; filterByExample&#39;查询。

虽然Timo的上述答案可能是更好的解决方案。

答案 4 :(得分:0)

您可以执行以下操作:

private BooleanExpression isFirstNameLike(String firstName){
    final QCustomer customer = QCustomer.customer;
    return customer.firstName.isNull().or(customer.firstName.like(firstName));
}

private BooleanExpression isStatutEq(StatusEnum status){
    final QCustomer customer = QCustomer.customer;
    return customer.status.isNull().or(customer.status.eq(status));    
}

或者,如果您想真正匹配firstName和/或状态,请更改

.isNull().or(...) to isNotNull().and(...)