Sql JPA中的自定义连接条件

Sql JPA中的自定义连接条件,sql,jpa,jpql,spring-data-jpa,Sql,Jpa,Jpql,Spring Data Jpa,是否可以在JPA中指定自定义联接条件(jpql或通过criteria api) select .. from .. join ... on (... <custom criteria> ) select..from..join..on(…) 我之所以需要它,是因为我想在一个日期范围内加入一组表(一个是具有事实堆栈的历史表) **更新** 可以在JPA(2.1>)中指定其他连接条件/条件。请参阅接受答案(zxcf) Hibernate注意:尽管可以使用join..ON或使用j

是否可以在JPA中指定自定义联接条件(jpql或通过criteria api)

select .. from .. join ... on (... <custom criteria> )   
select..from..join..on(…)
我之所以需要它,是因为我想在一个日期范围内加入一组表(一个是具有事实堆栈的历史表)

**更新**

可以在JPA(2.1>)中指定其他连接条件/条件。请参阅接受答案(zxcf)


Hibernate注意:尽管可以使用join..ON或使用javax.persistence.criteria.join以编程方式指定其他联接条件,但不能使用引用不同表的条件,只能使用引用相同表(而不是层次结构中更高的表)的条件受支持的请参见:

除非两个实体之间存在明确的关系,否则不能使用
JOIN
关键字-如果存在关系,可以使用:

SELECT e FROM Employee e JOIN e.projects p
您可以通过在关键字上使用
(请注意,这适用于
JPA 2.1
),进一步缩小您的
JOIN

如果要定义连接两个未定义关系的实体的
连接
,应在
WHERE
子句中使用附加条件:

SELECT e FROM Employee e, Projects p WHERE e.projectId = p.id
更新

如果在版本2.4或更高版本中使用
EclipseLink
(或者它是您的JPA提供商),则可以在
JOIN..ON
子句中使用自定义条件,因为EclipseLink还支持在两个根级对象之间使用ON子句

SELECT e FROM Employee e LEFT JOIN MailingAddress a ON e.address = a.address

我认为Dobrowolski的答案需要更新以供将来参考,因为这是EclipseLink不再独家提供的功能(至少对于与无关实体相关的功能)。如果您使用Hibernate(5.1或更高版本),现在就可以在无关实体上声明显式联接(即没有显式联接)使用JPQL/HQL,您可以从中看到:

EntityManager em=emf.createEntityManager();
em.getTransaction().begin();
List results=em.createQuery(“选择p.firstName、p.lastName、n.phoneNumber FROM Person p JOIN PhoneBookEntry n ON p.firstName=n.firstName和p.lastName=n.lastName”).getResultList();
对于(对象[]结果:结果){
log.info(结果[0]+“”+结果[1]+“-”+结果[2]);
}
em.getTransaction().commit();
em.close();

where子句中的条件/限制仅适用于通常不可用的隐式联接。答案可靠
SELECT e FROM Employee e LEFT JOIN MailingAddress a ON e.address = a.address
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

List<Object[]> results = em.createQuery("SELECT p.firstName, p.lastName, n.phoneNumber FROM Person p JOIN PhoneBookEntry n ON p.firstName = n.firstName AND p.lastName = n.lastName").getResultList();

for (Object[] result : results) {
    log.info(result[0] + " " + result[1] + " - " + result[2]);
}

em.getTransaction().commit();
em.close();