27

两个数据库表具有外键关系。

它们由 JPA 映射到两个实体AB,但是连接列是从实体中手动删除的,因此在 JPA 世界中,AB类不相关,您无法通过字段/属性从一个导航到另一个。

使用 JPA Criteria API,是否可以创建连接两个表的查询?

我在互联网上找到的所有示例都使用连接列来实现目标,但是,如上所述,它已从代码中删除,因为大多数时候我对AB之间的关系不感兴趣,而且我担心可能的开销.

4

5 回答 5

32

第一:外键关系不仅用于导航。它们主要用于确保关系中没有引入虚假值。它们还可以帮助数据库进行查询优化。我建议你重新考虑一下。

无论如何,要创建一个使用多个不相关实体的查询,您需要将它们作为from( root) 实体(就像您在 SQL 或 JPQL 中所做的那样)

SELECT .... FROM Link l, Training t WHERE l.attribute = t.attribute;

Root<Link> rootLink = criteriaQuery.from(Link.class);
Root<Training> rootTraining = criteriaQuery.from(Training.class);
...
criteriaQuery.where(
    criteriaBuilder.equal(rootLink.get(link_.linkAttribute), trainingLink));
于 2013-06-14T10:34:32.750 回答
6

从 Hibernate 5.1 开始,您可以在使用 JPQL 和 HQL 时加入不相关的实体:

Tuple postViewCount = entityManager.createQuery(
    "select p as post, count(pv) as page_views " +
    "from Post p " +
    "left join PageView pv on p.slug = pv.slug " +
    "where p.title = :title " +
    "group by p", Tuple.class)
.setParameter("title", "Presentations")
.getSingleResult();

但是,此功能在 Criteria API 中不可用,因为这需要 API 扩展。

解决方案

虽然您可以尝试使用两个Root对象并通过 WHERE 子句谓词模拟 INNER JOIN,但生成的 SQL 并不是解决此问题的最佳方法。

您应该考虑使用jOOQ,因为除了让您能够以任何可能的方式连接表之外,如果您将生成的 SQL 查询传递给 JPAcreateNativeQuery方法,您还可以获取实体。

于 2019-09-20T13:25:53.167 回答
4

最新的 JPA 规范 (2.1) 未涵盖加入无关实体

但是 Hibernate 5.1.0+ 和 EclipseLink 2.4.0+ 支持 ad hoc join。 http://blog.anthavio.net/2016/03/join-unrelated-entities-in-jpa.html

另一种可能性是本机查询 http://www.oracle.com/technetwork/articles/vasiliev-jpql-087123.html

于 2016-03-18T15:04:12.527 回答
0

可以为连接查询创建视图并为此视图创建实体,并且 JpaRepository 可以与用于表的通常实体类似地使用。如果你需要动态构建 where 子句,在这个视图实体之上构建它仍然是可行的

于 2021-06-03T07:43:06.917 回答
0

您可以使用 Blaze-persistence 的 JPA Criteria 实现,该实现转换为 JPQL/HQL,并提供该功能作为 JPA Criteria API 的扩展。

在自述文件中查找“Blaze-Persistence JPA-Criteria 模块依赖项”:https ://github.com/Blazebit/blaze-persistence/blob/master/README.md

然后使用BlazeCriteriaBuilder cb = BlazeCriteria.get(criteriaBuilderFactory)并最终blazeCriteriaQuery.getCriteriaBuilder(entityManager)呈现 JPA Criteria Query 对象。

于 2019-09-21T06:15:18.193 回答