gpt4 book ai didi

jpa - JPQL 查询 : how to filter rows on a relationship?

转载 作者:行者123 更新时间:2023-12-04 18:23:23 28 4
gpt4 key购买 nike

我是 JPA 2.0 的新手,几乎没有什么我不明白的。

我有几张 table :



CUST table (for customers)
--------------------------
CUST_ID (pk, integer)
CUST_NAME (varchar)





ORD table (for orders)
----------------------
ORD_ID (pk, integer)
ORD_STATUS (char) can be: 'N' for new, 'S' for shipped, 'D' for delivered
CUST_ID (fk, integer)


这种关系是简单的“一对多”(每个客户都可以下很多订单)。

表格内容:


CUST_ID | CUST_NAME
-------------------
1 | elcaro
2 | tfosorcim
3 | elppa





ORD_ID | ORD_STATUS | CUST_ID
-----------------------------
2 | N | 1
3 | N | 1
4 | N | 1
5 | S | 1
6 | S | 1
7 | D | 1
8 | D | 1
9 | D | 1
10 | D | 2
11 | N | 2
12 | S | 3
13 | S | 3


以下是我注释类的方式:


@Entity(name = "Customer")
@Table(name = "CUST")
public class Customer implements Serializable
{
private static final long serialVersionUID = 1L;

@Id
@Column(name = "CUST_ID")
private Integer id;

@Column(name = "CUST_NAME")
private String name;

@OneToMany(mappedBy = "customer")
private List<Order> orders;

// Default constructor, getters and setters (no annotations on these)
}





@Entity(name = "Order")
@Table(name = "ORD")
public class Order implements Serializable
{
private static final long serialVersionUID = 1L;

@Id
@Column(name = "ORD_ID")
private Integer id;

@Column(name = "ORD_STATUS")
private Character status;

@ManyToOne
@JoinColumns
(
{
@JoinColumn(name = "CUST_ID", referencedColumnName = "CUST_ID")
}
)
private Customer customer;

// Default constructor, getters and setters (no annotations on these)
}


一切正常,以下 JPQL 查询产生了我预期的结果:
`select c from Customer c`

它返回三个 Customer 类型的对象,每个对象都包含属于该客户的订单。

但是现在,我想提取状态为“N”的订单的客户列表,以及相关的订单(当然,只有状态为“N”的订单)。
回到过去的美好时光,我会写一个这样的 SQL 查询:


select c.cust_id,
c.cust_name,
o.ord_id,
o.ord_status
from cust c
inner join ord o on (o.cust_id = c.cust_id)
where o.ord_status = 'N'


它会返回以下结果集:


CUST_ID | CUST_NAME | ORD_ID | ORD_STATUS
-----------------------------------------
1 | elcaro | 2 | N
1 | elcaro | 3 | N
1 | elcaro | 4 | N
2 | tfosorcim | 11 | N


但是,以下 JPQL 查询不会产生预期的结果:
`select distinct c from Customer c join c.orders o where o.status = 'N'`

它返回正确的客户集(客户“elppa”没有任何状态“N”订单并被正确排除),但每个客户都包含完整的订单集,无论状态如何。
似乎只评估“where”子句以确定必须提取哪组客户,然后持久性提供程序开始导航关系以提取完整的订单集。
稍微想一想,我必须承认这是有道理的。

然后我尝试了另一个 JPQL 查询:
`select c, o from Customer c join c.orders o where o.status = 'N'`

此 JPQL 查询产生的结果与前一个 SQL 查询产生的结果相似:每个结果(预期为 4 个结果)是一个 2 对象数组,第一个对象是 Customer 类型,第二个对象是 Order 类型。但是,再次,客户类型的对象包含完整的相关订单集(正如我所料,这一次)。更不用说现在订单不包含在 Customer 对象中,而是单独返回,就像在 SQL 结果集中一样。

现在的问题是:
是否可以编写一个 JPQL 查询来过滤掉不仅没有处于“N”状态的订单的客户,还可以过滤掉不处于“N”状态的相关订单(在关系导航期间获取)?
我希望能够得到的是 2-customer 结果,其中每个客户仅包含其状态“N”订单。

我阅读了 Java EE 6 教程,其中一个示例(订单应用程序)的模式与我的相似,但我找不到这样的查询(在下载的源代码中)。

虽然我认为以上是标准行为,但我使用 Oracle Weblogic 12c 服务器(通过其 Eclipse 适配器),并且持久性提供程序似乎是 EclipseLink。

提前致谢。

此致,

斯特凡诺

最佳答案

JPA处理对象,一个对象是有身份的,不管怎么查询都是一样的。无论您的 where 子句是什么,返回的 Customer 对象仍然是相同的 Customer 对象并且应该具有相同的关系。这对于缓存、对象标识和一致性很重要。

您的第二个查询可能是做您想做的事情的正确方法。可以使用 JOIN FETCH 上的别名来做您想做的事情(从 EclipseLink 2.4 开始),但不推荐。

看,
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#JOIN_FETCH

关于jpa - JPQL 查询 : how to filter rows on a relationship?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10200985/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com