2012-11-23 58 views
5

我正在使用FilfetDto構建動態查詢 如果用戶在UI中填充了一些字段,則包含一些值但不是全部。 所以我就來測試每個屬性構造查詢過濾僅填充(不爲空)域:如何使用動態QueryDSL簡化語法,避免多個「if」

JPAQuery dslQuery = new JPAQuery(em); 

    dslQuery.from(book); 
    dslQuery.join(book.author, author);  

    String title = StringUtils.upperCase(StringUtils.trim(_filter.getTitle())); 
    if (StringUtils.isNotBlank(title)) { 
     dslQuery.where(book.title.upper().like(title)); 
    } 
    String isbn = StringUtils.trim(_filter.getIsbn()); 
    if (StringUtils.isNotBlank(isbn)) { 
     dslQuery.where(book.isbn.like(isbn)); 
    } 
    if (_filter.getAuthorId() != null) { 
     dslQuery.where(author.id.eq(_filter.getAuthorId())); 
    } 

有沒有辦法來抽象的「如果」用另一種更可讀的語法?

我想是這樣的:

JPAQuery dslQuery = new JPAQuery(em); 

    dslQuery.from(book); 
    dslQuery.join(book.author, author); 

    dslQuery.where(book.title.upperIfNotBlank().like(title)); 
    dslQuery.where(book.isbn.likeIfNotNull(isbn)); 
    dslQuery.where(author.id.eqIfNotNull(_filter.getAuthorId())); 

這將是很好,如果「IfNotNull」可以開啓,甚至是默認的行爲...
所以它最終會是這樣的:

dslQuery.where(book.title.upper().like(title)); 
    dslQuery.where(book.isbn.like(isbn)); 
    dslQuery.where(author.id.eq(_filter.getAuthorId())); 

回答

3

有沒有辦法來抽象的「如果」用另一種更可讀的語法?

不,可能不會有。 Querydsl表達式的目標是儘量接近底層持久化技術所使用的形式。

如果您想在您自己的項目中使用這樣的方法,可以隨意將它放入您自己的AbstractJPAQuery的子類中。 Querydsl查詢旨在針對這些情況進行定製。

1

我創建了一個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時,這是非常有用的,非常乾淨/可讀'查詢。