2012-01-10 91 views
3

我們正在開發一個使用EJB連接到數據庫的Web應用程序。來自子句中的JPA子查詢

在我們的數據庫模型中,我們有一個移動設備表,另一個具有功能,最後一個映射功能的值與手機型號。 模型(id_model,...) 功能(id_feature,...) model_features(id_model,id_feature,值)

我們要執行一個查詢,得到的匹配特徵數量排序的模型。也就是說,我們通過一系列功能匹配(即從1到9), ,並且我們希望所有包含'yes'的設備作爲至少一個這些功能的值,並按前面所述對它們進行排序。

我們創建了一個SQL查詢,使這項任務,它的工作原理:

SELECT CONCAT(subquery.numberf*100/9,"%") AS "Features", subquery.idModel AS "ID model" 
FROM (select count(*) AS numberf, id_model AS idModel 
     FROM model_features 
     WHERE value LIKE '%Yes%' AND id_feature IN(1,2,3,4,5,6,7,8,9) 
     GROUP BY id_model) subquery 
WHERE subquery.numberf > 0 
ORDER BY subquery.numberf DESC 

由於我們使用JPA,因此,我們一定要建立JPQL querys,它不可能包含在subquerys FROM子句,我們想知道 是否可以將子查詢「傳遞」到WHERE子句是可能的,並且不會以不良方式影響性能。我們該怎麼辦?

+1

你能只使用一個本地查詢?看起來最終結果更多的是一個集合而不是一個實體。 – wrschneider 2012-01-10 20:34:21

+0

我們已經考慮過這種可能性,但如果可能的話,我們會用jpa來做。謝謝@ wrschneider99 – frayab 2012-01-10 22:11:34

回答

2

最後我們解決了使用本地查詢:

String query = "SELECT ROUND(subquery.numberf*100/" + features + ",0) AS \"matches\", m.id_model AS \"id_model\", m.name AS \"name\", m.brand AS \"brand\", m.url_pict AS \"url_picture\"" 
       + " FROM (select count(*) AS numberf, id_model AS idModel FROM model_features WHERE value LIKE '%Yes%' " 
       + "AND id_feature IN(" + idFeatures + ") GROUP BY id_model) subquery, Models m WHERE subquery.numberf > 0 " 
       + "AND subquery.idModel = m.id_model ORDER BY subquery.numberf DESC, m.name"; 
return em.createNativeQuery(query).getResultList(); 
+2

這個類不應該是一個實體:它不會被JPA持久化。這只是一個DTO。 – 2012-01-11 16:56:09

+0

em.createNativeQuery(query,ModelMatches.class).getResultList();返回實體「ModelMatches」的元素列表,如果它不是實體,則可以做它 – frayab 2012-01-11 17:09:34

+1

僅僅因爲此方法需要實體並不意味着您的類應該是實體。您不希望JPA將您可能對此對象所做的任何更改保留在表中,對嗎?您可以執行SQL查詢並根據查詢結果(Object []實例)自己創建DTO實例。 – 2012-01-11 17:18:36