JPA计算其子类的一对多关系

时间:2016-12-12 21:20:12

标签: java jpa count one-to-many jpql

我正在为我的项目使用JPA,我想知道有任何方法可以将其子类计为一对多关系。例如,假设有一个订单类有多个项目,我需要显示一个订单列表。

@Entity
@Table
public class Order {
    ...
    @Id
    private Long orderId;
    @OneToMany
    private List<OrderItem> orderItems;
}

对于列表,我需要显示订购的商品数量和取消的商品数量。所以,我添加了这样的功能

    @OneToMany
    private List<OrderItem> orderItems;
    ...
    public Long countOrderedItems() {
        Long count = 0;
        orderItems.forEach(orderItem -> {
            if(orderItem.getStatus().equals(Status.ORDERED)){
                count++;
            }
        });
        return count;
    }
    public Long countCancelItems() {
        Long count = 0;
        orderItems.forEach(orderItem -> {
            if(orderItem.getStatus().equals(Status.CANCEL)){
                count++;
            }
        });
        return count;
    }

然而,这看起来效率低下,我希望在从存储库获取数据时直接获取这两个值,如:

@Query("SELECT o, (SELECT COUNT(oi) FROM OrderItem oi WHERE oi.Order.orderId = o.orderId AND oi.status = 'ORDERED') FROM Order o"); 

但是,我知道这不是正确的JPQL,我想知道如何在JPA中有效地获取这些值。

2 个答案:

答案 0 :(得分:1)

使用JPA 2.1功能JOIN ON

select o, count(io), count(io2) from Order o 
left join o.irderItem oi on oi.status = 'ORDERED'
left join o.irderItem ui on ui.status = 'CANCELED'
group by s
  

用于连接的连接条件来自映射的连接列。这意味着JPQL用户通常不必知道每个关系的连接方式。在某些情况下,最好在连接条件中附加附加条件,通常在外连接的情况下。这可以通过ON子句来完成。

答案 1 :(得分:0)

也可以通过单一连接来完成:

HSQL:

select o, 
sum(case when oi.itemStatus = 'ORDERED' then 1 else 0 end), 
sum(case when oi.itemStatus = 'CANCELED' then 1 else 0 end) 
from OrderItem oi 
right outer join Order o on oi.orderId = o.id
group by o.id

JPA存储库:

@Query("select new example.springboot.jpa.custom.OrderSummary(o, " +
        "sum(case when oi.itemStatus = 1 then 1 else 0 end) as orderedItems, " +
        "sum(case when oi.itemStatus = 1 then 1 else 0 end) as canceledItems)  " +
        "from OrderItem oi right join oi.customOrder o group by o")
List<OrderSummary> findAllOrdersSummary();

你可以在这里找到完整的例子: https://github.com/abhilekhsingh041992/spring-boot-samples/blob/master/jpa/src/main/java/example/springboot/jpa/repository/OrderRepository.java