带有两个子查询/连接的 JPA 标准选择
Posted
技术标签:
【中文标题】带有两个子查询/连接的 JPA 标准选择【英文标题】:JPA Criteria select with two subqueries / joins 【发布时间】:2016-01-13 22:03:52 【问题描述】:我整天都在战斗,我想不通。我是 JPA 初学者,所以现在 Criteria API 对我来说是一场噩梦。问题:
我有 3 个实体:Policy、Customer、Insurer。保单引用了客户和保险公司(此处急切获取)。客户有保单清单,Insurer 也有(这里是懒惰的获取)。
我正在尝试以下述方式 (SQL) 查找所有策略:
SELECT * FROM POLICY as p WHERE
p.CUSTOMER_ID IN (SELECT ID FROM CUSTOMER as c WHERE [customerPredicates])
AND
p.INSURER_ID IN (SELECT ID FROM INSURER as i WHERE [insurerPredicates])
AND
[policyPredicates]
其中 CUSTOMER_ID / INSURER_ID 是从 Policy 中的 @ManyToOne 关系生成的 JoinColumns。
customerPredicates / insurancePredicates / policyPredicates 是谓词列表(根据给定搜索条件准备的“where”条件)。
如何在 Criteria API 中实现这一点?创建此类查询的规则/良好做法是什么?
【问题讨论】:
【参考方案1】:尝试先重写 SQL 以使用 JOINS
SELECT *
FROM POLICY as p
INNER JOIN CUSTOMER as c ON p.CUSTOMER_ID = c.ID
INNER JOIN INSURER as i ON p.INSURER_ID = i.ID
WHERE [customerPredicates])
AND
[insurerPredicates])
AND
[policyPredicates]
您所需要的只是标准 api,用于获取主要标准(用于 Policy 实体)并为 Customer 实体和 Insurer 实体创建别名。
Criteria criteria = session.createCriteria(Policy.class, "p");
criteria.setFetchMode("p.Customer", FetchMode.JOIN);
criteria.createAlias("p.Customer", "c");
并将您的限制添加到 Customer 的“c”别名。
保险公司也是如此
【讨论】:
是的,重写这个 SQL 可以帮助我解决这个问题,但我想使用纯 JPA Criteria API,而不是 Hibernate 的 Crtiteria。我试图理解 JPA Criteria 中的获取和别名,但我感到困惑...... JPA 也有别名。所以你可以使用与纯 JPA Criteria API 相同的逻辑以上是关于带有两个子查询/连接的 JPA 标准选择的主要内容,如果未能解决你的问题,请参考以下文章
选择带有“is null”子句的查询和子选择/左连接不返回结果
在 JPA 的 SQL 查询中的 FROM 语句中包含子查询