2016-12-12 2 views
2

Я использую JPA для своего проекта, и я хотел бы знать, что есть какой-либо способ подсчитать его подкласс для отношений друг к другу. Например, допустим, что есть класс заказа, который имеет несколько элементов, и мне нужно отобразить список заказов.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.

ответ

0

Использование 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.

+0

Я думаю, что это не vio JPQL, так что он выглядит нормально. Однако я не знаю, как сопоставить 'count (io)' с полем. Если я добавлю переменную-член 'numberOfOrderedItems' в класс Order, то как ее можно сопоставить? Потому что я попробовал это, и он показал «Неизвестный столбец» order0_.number_of_ordered_items 'в' списке полей '' –

+0

Он не может быть отображен в сущность. Список возвращаемых неидентифицированных запросов будет содержать Object [] {Order, int, int} –

+0

Наконец, я добавил два поля для подсчета упорядоченного и отмененного состояния с @Transient и отобразил поля в функции построения. Итак, моя окончательная версия JPQL - это «SELECT new Order (o.orderId, ..., count (io), count (io2)) FROM Order o ...' Спасибо за вашу помощь @peter –

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 Repository:

@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

Смежные вопросы