Select 实体中包含的列表的子集

Select subset of the list contained in an entity

假设我想要获取 ID 小于 10 的 MyEntity 的所有行。此实体包含 Another 实体的列表。我希望此列表仅由 listAnother 的一个子集获取。此子集仅包含 Another,其中包含的 user 是特定的。

基本上在SQL中是这样的:

SELECT * FROM myentity m
LEFT JOIN another a
ON m.idTable=a.my_entity
AND a.user = "test1"
WHERE m.idTable < 10;

但是我没有设法将此查询转换为 jpql。

我的实体是这样的:

@Entity
public class MyEntity implements Serializable {    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int idTable;

    @OneToMany(mappedBy = "myEntity")
    private List<Another> listAnother;

}

@Entity
public class Another implements Serializable {    
    @Id
    private int idAnother;

    // bi-directional many-to-one association to Thethread
    @ManyToOne(fetch = FetchType.LAZY)
    private MyEntity myEntity;

    @ManyToOne(fetch = FetchType.LAZY)
    private User user;
}

@Entity
public class User implements Serializable {

    @Id
    private String username;
}

在 jpa 中我可以这样做:

SELECT m FROM MyEntity where m.idTable < 10;

然后对于我从此列表中获得的每个实体调用此:

SELECT a FROM Another Where a.user.username=:'test' AND a.myEntity=:entity;

但是我想在一个查询中一次完成所有操作。我可以用标准来做到这一点吗?我没有花时间学习它,但如果可能的话,我会的。

在休眠中,您可以使用 Filters 和 FilterJoinTable。 Here you can read how to do that. Similar problem was solved here.

您需要扩展用于检查用户名 (a.user.username=:'test') 的逻辑,该逻辑通过将其提升一级来实现任何事物与用户之间的多对一关系直到 myEntity,然后也将其用于一对多关系 -

 SELECT m FROM MyEntity where m.idTable < 10 and (m.listAnother.user.username=:'test')

现在不需要连接条件 "m.listAnother.myEntity=:entity",因为在我们的查询中,我们从特定的 myEntity 开始,然后向下移动到 listAnother.user.username。

我没有 table 定义来自己尝试这个查询,确切的 SQL 可能需要一些调整 - 但从逻辑上讲它应该像我上面展示的那样工作,即就是这样您将 Another 与 User 加入,就像您可以通过向下遍历子 listAnother 将 MyEntity 与 Another 加入一样。

JPQL 和 Critaria API 在您可以用它们表达的内容方面是平等的。 JPQL 可以用 Criteria 实现,反之亦然。

使用 JPQL,您可以通过这种方式将 2 个查询简单地合并为一个:

SELECT a FROM Another a Where a.user.username=:test AND a.myEntity.idTable < 10

您可以使用点符号 (.) 连接查询中的多个实体,前提是关系是 X 对一的。如果你有 X-to-many 关系,你需要使用 JPQL JOIN,这不是很复杂。使用 (LEFT) JOIN 的示例:

SELECT m FROM MyEntity m LEFT JOIN m.listAnother a Where a.user.username=:test AND m.idTable < 10

结果当然不相等 - 在第一种情况下,您将获得另一个实体的列表,您可以通过 a.myEntity 获得 MyEntity,在第二种情况下,您将获得 MyEntity 的列表,它们都位于至少一个给定用户的另一个实体