2010-01-11 101 views
3

這是同一個問題:如何根據用戶的選擇動態生成SQL查詢?

How to dynamically generate SQL query based on user's selections?

唯一的區別是,我希望看到的解決方案還使用Java/JPA(+可能的EclipseLink或Hibernate的特定擴展)。

我需要創建一個GUI,使用它可以選擇用於查詢數據庫以查找合適人員的幾個屬性。我正在尋找如何根據用戶的選擇動態生成數據庫查詢的想法。

查詢將包含幾個字段,但得到的想法,我會包括只有三個低於爲例:

  • 職業 - 可以有0到n職業字符串。如果給出職業字符串,其中一個必須匹配。

  • 年齡 - 年齡可被給定爲:

    1. 精確匹配(30)
    2. 範圍(例如30-40)
    3. 比的值(-40)
    4. 少超過一個值(30-)

年齡參數在查詢中是可選的。另外,用戶可以指定年齡是否是必需的參數。如果不是必需的,並且一個人沒有年齡是他/她的個人資料,那麼這個人將忽略年齡標準。

  • 高度 - 年齡相似

查詢示例:

沒有標準已經給出:

select * from persons 

唯一的佔領已經給出:

select * from persons where occupation = 'dentist' 

一些職業被賦予了:

select * from persons where (occupation = 'dentist' or occupation = 'engineer') 

年齡已經給出一個大於價值,而且它需要在個人資料存在:

select * from persons where age >= 30 

身高已經給出了作爲並且不需要存在於人的簡檔上:

select * from persons where (height is null or (height >= 30 and height <= 40)) 

Combina不同的標準重刑:

select * from persons where occupation = 'dentist' and age >= 30 and (height is null or (height >= 30 and height <= 40)) 

我已經執行的代碼,它能夠生成查詢字符串形式的,但可以肯定的是不是太漂亮。我正在尋找想法什麼是最有效和最漂亮的方式來實現這一點。

回答

0

在我的代碼中,我使用ANDOR這個對象。他們將列表作爲參數(對於Java 5的可變參數看起來不錯),並將它們與Strings中的必要空格和括號連接起來。僞代碼:

AND(WhereCond ... conds) { this.conds = conds; } 
toString() { return conds.length == 0 ? "" : "(" + join(conds, " AND ") + ")" }; 

其中join()對象數組字符串數組轉換,然後加入與參數的元素。

1

如果您想在JPA 1.X中執行此操作,您可以使用自定義查詢生成器,如http://rrusin.blogspot.com/2010/02/jpa-query-builder.html所述。 這樣能夠創建查詢是這樣的:

return new JpaQueryBuilder().buildQuery(em, 
       new Object[] { 
        "select c from Car c where c.name is not null", 
        new JQBParam("name", name, " and c.name = :name"), 
        new JQBParam("type", type, " and c.type = :type") 
       } 
      ) 
1

我使用Querydsl框架,因爲我使用JPA 1.0不包括標準API,我也需要你描述的特徵。編寫Querydsl代碼很簡單,代碼比Criteria API代碼短。 Querydsl可以免費使用,它支持類型安全查詢。

3

有許多不同的工具,我認爲最好的是querydsltorpedoqueryēObject Query,這三年讓編寫類型安全的查詢,否則你可以使用標準的API,如果你正在使用JPA 2還JPA2 Typesafe Query

所有這些工具,你可以在運行時建立一個查詢!