【问题标题】:JPA subquery in from clausefrom 子句中的 JPA 子查询
【发布时间】:2012-01-10 17:36:35
【问题描述】:

我们正在开发一个使用 EJB 连接到数据库的 Web 应用程序。

在我们的 DB 模型中,我们有一个移动设备表,另一个包含功能表,最后一个将功能值与手机型号进行映射。 模型(id_model,...) 特征(id_feature,...) model_features (id_model, id_feature, value)

我们想要执行一个查询,以获取按匹配特征数量排序的模型。也就是说,我们传递要匹配的特征列表(即从 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 查询,因此无法在 FROM 子句中包含子查询,我们想知道是否 我们可以将子查询“传递”到 WHERE 子句是可能的,并且不会以不好的方式影响性能。我们该怎么办?

【问题讨论】:

  • 你可以只使用原生查询吗?看起来最终结果更像是一个聚合而不是一个实体。
  • 我们已经考虑过这种可能性,但如果可能的话,我们将使用 jpa。谢谢@wrschneider99

标签: mysql sql jakarta-ee jpa subquery


【解决方案1】:

最后我们使用原生查询解决了:

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

【讨论】:

  • 这个类不应该是一个实体:它不是由 JPA 持久化的。这只是一个 DTO。
  • em.createNativeQuery(query, ModelMatches.class).getResultList();返回实体“ModelMatches”的元素列表,如果它不是实体,则可以这样做
  • 仅仅因为这个方法需要一个实体并不意味着你的类就应该是一个实体。您不希望 JPA 将您可能对此对象所做的任何更改保存到表中,对吗?您可以执行 SQL 查询并根据查询结果(Object[] 实例)自己创建 DTO 实例。
  • 我知道,您的回答是正确的,但我们想使用实体管理器,这是获得所需结果的解决方案。
  • 你为什么不直接使用没有类参数的相同方法,并从自己返回的 Object[] 列表中创建 DTO 列表。这是正确的解决方案。
猜你喜欢
  • 2011-11-08
  • 2012-07-19
  • 1970-01-01
  • 2021-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-01
  • 1970-01-01
相关资源
最近更新 更多