2012-09-05 108 views
4

說我有CustomerQueryInfo豆具有以下屬性:返回一個QueryDSL BooleanExpression值爲true

  • 字符串的firstName
  • 字符串的lastName
  • StatusEnum狀態

我想執行一個「QueryDSL」使用此類型的對象搜索將返回客戶列表List<Customer>

如果CustomerQueryInfo的其中一個字段是null,我不想在搜索中使用它。因此,所有三個字段設置爲nullCustomerQueryInfo對象將返回所有客戶

我正在尋找使用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. 如何返回BooleanExpression計算結果爲真?
  2. 如果上述方法不可取,那麼建議的最佳做法是什麼?

回答

13

您可以放心地使用空謂詞這樣

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

,並使用其中

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

再次感謝你Timo。 – balteo

+0

不確定是否相關,但今天我碰到QueryDSL 3.5.0(使用spring-data-jpa)中的一個問題,其中'isTrue()'正確地返回了一切,但'eq(Boolean.TRUE)'沒有返回任何東西。但是'eq(Boolean.FALSE)'正常工作。這是一個錯誤? – EpicPandaForce

+0

跳過空位記錄在哪裏。是否可以對'BooleanExpression.and(Predicate)'做同樣的事情?當前空跳過是這裏的一個實現細節,當參數被標註爲@Nullable時,沒有記錄空行爲。 –

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

實施「過濾器」或「filterByExample時,這是非常有用的,非常乾淨/可讀'查詢。

雖然從Timo上面的答案可能是更好的解決方案。

7

與Java 8和BooleanBuilder可以實現優雅的方式是這樣的:

的Java 8可選& 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)); 
5

如何返回BooleanExpression那評估爲真?

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

看起來像一個很好的解決方案,但在我的情況下,我結束了'java.lang.UnsupportedOperationException:非法操作true = true \t at com.querydsl.mongodb.MongodbSerializer.visit(MongodbSerializer.java:259' – GaspardP

+0

Works with Oracle似乎是與MongoDB相關的一個問題 –

+0

當你找到MongoDB的工作解決方案時,請告訴我們,也許一些轉換爲'1 = 1'的東西有效?!我們只需要任何重複數據。 –

相關問題