2012-01-10 72 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