JPQL查询:如何在一个关系过滤行?(JPQL query: how to filter rows

2019-06-23 17:23发布

我是新来的JPA 2.0,有几件事情我不明白。

我有几个表:



    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`

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

但现在,我想提取有订单状态“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”秩序和正确除外),但每个客户包含全套的订单,不管状态。 如此看来,“其中”子句仅评估,以确定哪些客户的设置,必须提取,然后持久性提供开始导航的关系来提取全套订单。 思考一点点关于它,我必须承认,这是有道理的。

然后我尝试了另一种JPQL查询:

`select c, o from Customer c join c.orders o where o.status = 'N'`

此JPQL查询产生的结果是类似于由以前的SQL查询产生的那些:每个结果(4个结果如预期)是2-对象阵列,所述第一对象的类型是客户和所述第二对象的类型是级。 但同样,客户类型的对象包含了一整套相关的订单(如我所料,这一次)。 更何况,现在的订单不包含在客户对象,而是单独返回,就像在SQL结果集的事实。

现在的问题是:是否有可能写一个JPQL查询过滤掉,不仅客户没有在状态的顺序“N”,但相关订单(关系导航过程中取出)不在状态“ N”呢? 我希望能够得到的是一个2 - 客户的结果,其中每个客户只包含其状态“N”的订单。

我读了Java EE 6教程和的例子之一(该命令的应用)的模式类似于我的,但我找不到这样的查询(在下载的源代码)。

虽然我觉得上面的是标准的行为,我使用的Oracle WebLogic服务器12C(通过其Eclipse的适配器)和持久性提供看来是的EclipseLink。

提前致谢。

最好的祝福,

斯特凡诺

Answer 1:

JPA处理与对象和对象都有一个标识,是一样的,不管它是如何查询。 不管你的where子句是什么,返回的客户对象仍然是相同的客户对象,并应具有相同的关系。 这是高速缓存,对象身份和一致性很重要。

你的第二个查询可能是你想要做什么的正确方法。 它可以做什么你正在尝试使用别名做一个连接抓取(的EclipseLink 2.4),但不推荐。

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



文章来源: JPQL query: how to filter rows on a relationship?