我写了一个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实体是否是相同的继承树的一部分。 对,他们是。 但是,如果我从他们的基类中选择,我不相信我会在不同的子实体指定不同的字符串常量的一种方式,不是么? 如果我能选择一个实体的类名称,而不是一个字符串,我提供的,这可能成为我的目的了。 但我不知道这是可能的两种。 思考?
我做了一些更多的搜索和发现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
有些JPA提供商都支持UNION,
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#UNION
但您的查询似乎很复杂,和非面向对象的,所以使用原生SQL查询可能会是最好的。