JPQL继续选择记录,直到不满足条件

时间:2019-04-04 08:16:42

标签: java jpa jpql

正在努力应对以下情况:

实体

@Table(name = "orders")
public class OrderEntity {

@Id
@Column(name = "id")
@Type(type = "uuid-char")
private UUID id;

...

@Column(name = "total_items")
private Integer totalItems;

@Column(name = "create_date")
private LocalDateTime createDate;

}

我需要选择尽可能多的OrderEntity对象,直到totalItems的组合 SUM 小于或等于某个整数值(即500)为止。

所以,假设我在数据库中有3条记录:

  • OrderEntity1(totalItems = 100)
  • OrderEntity2(totalItems = 200)
  • OrderEntity3(totalItems = 300)

假设组合totalItems的阈值为500,则查询应返回OrderEntity1OrderEntity2。如果将阈值降低到250,则仅应返回OrderEntity1

使用Java代码,我会这样做:

        List<OrderEntity> orders = orderRepository.findAll();

        int threshold = 500;
        int aggregatedTotalItems = orders.get(0).getTotalItems();

        for (int i = 1; i < orders.size(); i++) {
            // Increment intermediate result
            aggregatedTotalItems  += orders.get(i).getTotalItems();

            // Validate intermediate result
            if (aggregatedTotalItems > threshold) {
                orders = orders.subList(0, i); // limit orders collection from first to (current - 1) order
            }
        }
    }

使用JPQL是否可以实现相同的目的?

1 个答案:

答案 0 :(得分:2)

这将非常简单,并且直接用标准SQL解决可能会更快:

SELECT *
FROM (
  SELECT 
    t.*,
    row_number() OVER (ORDER BY o.id) rn,
    count(*) OVER () c
  FROM (
    SELECT 
      o.* 
      SUM(total_items) OVER (ORDER BY o.id) s -- Replace by your order criteria
    FROM orders o
  ) t
  WHERE s < 500
) t
WHERE rn < c;

甚至MySQL 8现在也支持窗口功能。 JPQL不会。我衷心地怀疑您会发现使用JPQL的一种优雅而高效的解决方案。