JPA - 如何在查询多对多关系时防止不必要的连接
JPA - how to prevent an unnecessary join while querying many to many relationships
我有实体 Product 和 Category 通过简单的多对多关系连接。我想获得按单个类别过滤的分页产品列表。我正在尝试编写一个 Spring Data JPA
自动方法或一个 JPQL
查询方法来生成类似于以下内容的 SQL
:
select [...] FROM ProductToCategory ptc INNER JOIN Product p ON ptc.product_id=p.id WHERE ptc.category_id=? LIMIT ? OFFSET ?
由于 ProductToCategory
join table 不是 JPA entity
并且我无法在 JPQL
中引用它,我能想到的最接近的事情是:
@Query("SELECT p FROM Category c INNER JOIN c.products p WHERE c=:category")
Page<Product> findByCategories(@Param("category") Category category, Pageable pageable);
但是生成的 SQL
会产生与类别 table 的冗余连接,并在那里应用 where 子句,而不是 ProductToCategory
[=] 中的类别 id
table。有没有办法不求助于原生 SQL
?
我能看到的唯一方法是将一个实体映射到联接 table 并将多对多产品<>类别替换为指向来自两个产品的这个新实体的一对多关系和类别。
这样的更改实际上符合 Hibernate 最佳实践:
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/best-practices.html
Do not use exotic association mappings:
Practical test cases for real
many-to-many associations are rare. Most of the time you need
additional information stored in the "link table". In this case, it is
much better to use two one-to-many associations to an intermediate
link class. In fact, most associations are one-to-many and
many-to-one. For this reason, you should proceed cautiously when using
any other association style.
我有实体 Product 和 Category 通过简单的多对多关系连接。我想获得按单个类别过滤的分页产品列表。我正在尝试编写一个 Spring Data JPA
自动方法或一个 JPQL
查询方法来生成类似于以下内容的 SQL
:
select [...] FROM ProductToCategory ptc INNER JOIN Product p ON ptc.product_id=p.id WHERE ptc.category_id=? LIMIT ? OFFSET ?
由于 ProductToCategory
join table 不是 JPA entity
并且我无法在 JPQL
中引用它,我能想到的最接近的事情是:
@Query("SELECT p FROM Category c INNER JOIN c.products p WHERE c=:category")
Page<Product> findByCategories(@Param("category") Category category, Pageable pageable);
但是生成的 SQL
会产生与类别 table 的冗余连接,并在那里应用 where 子句,而不是 ProductToCategory
[=] 中的类别 id
table。有没有办法不求助于原生 SQL
?
我能看到的唯一方法是将一个实体映射到联接 table 并将多对多产品<>类别替换为指向来自两个产品的这个新实体的一对多关系和类别。
这样的更改实际上符合 Hibernate 最佳实践:
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/best-practices.html
Do not use exotic association mappings: Practical test cases for real many-to-many associations are rare. Most of the time you need additional information stored in the "link table". In this case, it is much better to use two one-to-many associations to an intermediate link class. In fact, most associations are one-to-many and many-to-one. For this reason, you should proceed cautiously when using any other association style.