JPQL相当于SQL查询中使用工会和选择常数(JPQL equivalent of SQL quer

2019-07-20 12:40发布

我写了一个SQL查询,基本上从多个表中选择,以确定哪些有,因为在特定日期创建的行。 我的SQL看起来是这样的:

SELECT widget_type FROM(
  SELECT 'A' as widget_type
  FROM widget_a
  WHERE creation_timestamp > :cutoff
  UNION
  SELECT 'B' as widget_type
  FROM widget_b
  WHERE creation_timestamp > :cutoff
) types
GROUP BY widget_type
HAVING count(*)>0

行之有效的SQL,但我最近发现,虽然JPA可以使用工会“每类表”多态查询执行, JPQL不支持工会的查询。 所以这让我想知道JPA是否有替代我可以用它来完成同样的事情。

在现实中,我将针对查询十几张桌子,而不是两个,所以我想避免这样做单独的查询。 我也想避免做一个本地的SQL查询可移植性原因。

在我挂到上面的问题,有人问映射到widget_a和widget_b实体是否是相同的继承树的一部分。 对,他们是。 但是,如果我从他们的基类中选择,我不相信我会在不同的子实体指定不同的字符串常量的一种方式,不是么? 如果我能选择一个实体的类名称,而不是一个字符串,我提供的,这可能成为我的目的了。 但我不知道这是可能的两种。 思考?

Answer 1:

我做了一些更多的搜索和发现JPA的(貌似不起眼)的功能,完美的服务我的目的。 我发现的是,JPA 2的type的关键字,可以让你多态查询限制到特定的子类,就像这样:

SELECT widget
FROM BaseWidget widget
WHERE TYPE(widget) in (WidgetB, WidgetC)

我发现,JPA(或至少Hibernate作为JPA实现)允许您使用type不仅制约,而且在选择列表。 这大约是我的查询结束什么看起来像:

SELECT DISTINCT TYPE(widget)
FROM BaseWidget widget
WHERE widget.creationTimestamp > :cutoff

该查询返回的列表Class的对象。 我原来的查询是选择字符串常量,因为最接近的什么,我会在SQL这样做。 选择Class是在我的情况确实较好。 可是如果我不喜欢选择基于实体的类型常量,那就是精确的情况下的Oracle文档使用说明case语句:

SELECT p.name
CASE TYPE(p)
  WHEN Student THEN 'kid'
  WHEN Guardian THEN 'adult'
  WHEN Staff THEN 'adult'
  ELSE 'unknown'
END
FROM Person p


Answer 2:

有些JPA提供商都支持UNION,

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#UNION

但您的查询似乎很复杂,和非面向对象的,所以使用原生SQL查询可能会是最好的。



文章来源: JPQL equivalent of SQL query using unions and selecting constants