JPA/JPQL中如何过滤集合?

6

我有两个实体:

@Entity
public class Customer  implements java.io.Serializable {
...
    @OneToMany(fetch=FetchType.EAGER, mappedBy="customer")
    private Set<CustomerOrder> customerOrders;
...


@Entity
public class CustomerOrder  implements java.io.Serializable {
....        

    private double cost;

    @ManyToOne
    @JoinColumn(name="CUST_ID")
    public Customer customer;
...

现在在我的JPQL中,我想返回那些CustomerOrder.cost>1000的客户。例如,有三个客户A、B和C。A有两个订单,成本分别为1000和2000。B有三个订单,成本分别为2000、3000和500。C有一个订单,成本为500。现在我想获取这三个客户:A仅返回成本为2000的订单;B返回成本为2000和3000的订单;C返回一个空的订单集合。
但是以下代码将始终返回完整的集合:
select c from Customer c, in(c.customerOrders) o where o.cost>1000

我该如何在JPQL或特定的Hibernate中实现这个功能?
3个回答

7

所提出的查询与以下查询等效:

select c from Customer c inner join c.customerOrders o where o.cost > 1000

这个函数会返回所有至少有一笔订单的消费金额大于1000的客户。

我建议使用反向连接并选择订单 - 这在语义上与您所需的结果相同,但结构上略有不同:

select o from CustomerOrder o where o.cost > 1000

现在,Hibernate有一个非JPA的功能叫做Filter,应该可以完全满足您的需求 - 请参见这里:http://www.hibernate.org/hib_docs/reference/en/html/filters.html

jscoot表示它返回所有的行,因此你的第一个查询可能与他的查询不等同,因为C只有一个订单,其成本<1000。 - David Mann

2

试试这个

select c from Customer c join CustomerOrder o with o.cost > 1000

如果客户有两个订单的成本均大于1000,可能会返回两次该客户信息。你可以使用group by来解决此问题。请保留HTML标签。
select c from Customer c join CustomerOrder o with o.cost > 1000
group by c

0

在性能方面,OneToMany关系似乎是个不好的主意。

但为什么这个不行:select o from CustomerOrder o where o.cost > 1000; 然后从结果列表中提取客户信息呢?


为什么这是个坏主意? - Jimmy T.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接