JPA何时使用实体类型的路径而不是Join?

时间:2018-04-22 05:37:41

标签: jpa join

JPA规范中的一个例子:

CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
Root<Customer> customer = q.from(Customer.class);
Join<Customer, Order> order = customer.join(Customer_.orders);
q.where(cb.equal(cb.treat(order.get(Order_.product), Book.class)
.get(Book_.name),
"Iliad"));
q.select(customer);

order.product是where子句中的路径。如果不加入,如何访问 产品的名称属性(书)?它实际上是转换为SQL时的表连接吗?如果是这种情况,路径之间有什么区别 并加入这个例子?

    Order        Product
----------      -------------
    productId    id     name

1 个答案:

答案 0 :(得分:1)

  

转换为SQL时它实际上是表连接吗?

是的,确实如此。

  

此示例中路径和连接的区别是什么?

让我解释一下使用JPQL,它会更清楚。您的代码大致相当于:

SELECT c FROM Customer c
JOIN c.orders o
WHERE o.product.name = 'Illiad'

可以通过隐式连接(使用路径导航)和显式连接(使用JOIN)查询单值关联。重要的是要记住默认情况下隐式连接是内部连接。因此,上述查询等同于:

SELECT c FROM Customer c
JOIN c.orders o
JOIN o.product p
WHERE p.name = 'Illiad'

此语法更详细,但允许您指定连接类型(如果需要)。

多值关联的行为略有不同。以下查询:

SELECT c FROM Customer c
JOIN c.orders.product.name = 'Illiad'

不会编译。此处不能使用简写语法,因为c.orders表示整个集合而不是其各个元素。要引用单个元素,我们需要取消引用集合,这使JOIN c.orders o语法成为必需(别名o现在引用c.orders中的单个元素)

另一方面,当引用整个多值关联时,不需要显式连接,例如:

SELECT c FROM Customer c
WHERE SIZE(c.orders) > 5

SELECT c.orders FROM Customer c