如何使用 JPA 标准 API 联接不相关的实体

2022-09-01 13:06:14

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

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

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

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


答案 1

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

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

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));

答案 2

从 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();

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

解决方案

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

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


推荐