两个数据库表具有外键关系。
它们被JPA映射到两个实体 A 和 B ,但是从实体中手动删除了连接列,因此在JPA世界类中 A < / strong>与 B 无关,您无法通过字段/属性从一个导航到另一个。
使用条件api是否可以创建一个连接两个表的查询?
我在互联网上找到的所有示例都使用了连接列来实现目标,但是,如上所述,它已从代码中删除,因为大多数时候我对 A 之间的关系不感兴趣 B ,我担心可能的开销。
答案 0 :(得分:20)
第一:外键关系不仅适用于导航。它们主要用于确保在关系中不引入虚假值。它们还可以帮助数据库进行查询优化。我建议你重新考虑一下。
无论如何,要创建使用多个不相关实体的查询,您需要将它们设置为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));
答案 1 :(得分:5)
加入不相关的实体不受最新JPA规范(2.1)
的保护然而,Hibernate 5.1.0+和EclipseLink 2.4.0+支持ad hoc连接。 http://blog.anthavio.net/2016/03/join-unrelated-entities-in-jpa.html
另一种可能性是本机查询 http://www.oracle.com/technetwork/articles/vasiliev-jpql-087123.html
答案 2 :(得分:0)
正如我在this article中所述,自Hibernate 5.1起,您可以在使用JPQL和HQL时加入不相关的实体:
'Enter'
但是,此功能在Criteria API中不可用,因为这需要API扩展。
尽管您可以尝试使用两个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();
对象并通过WHERE子句谓词模拟INNER JOIN,但生成的SQL并不是解决此问题的最佳方法。
您应该考虑使用jOOQ,因为除了使您能够以任何可能的方式联接表之外,如果将生成的SQL查询传递给JPA createNativeQuery方法,则还可以获取实体。
答案 3 :(得分: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对象。
答案 4 :(得分:0)
可以为连接查询创建视图并为此视图创建实体,并且 JpaRepository 可以像通常的表实体一样使用。 如果需要动态构建where-clause,在这个view-entity之上构建还是可行的