在 spring 引导中使用多个 OR 条件进行内部连接

Inner join with more than one OR conditions in spring boot

我正在使用 spring 引导规范并尝试执行如下所示的查询 -

SELECT DISTINCT
    p.name
FROM
    partner p
        INNER JOIN
    detail d ON p.detail_id = d.id
        INNER JOIN
    account a ON d.account_id = a.id
        OR d.crm_id = a.top_parent
        OR d.crm_id = a.global_partner

我用过密码

  Join<Partner, Detail> details = root.join("detail");
  Join<Detail, Account> account = details.join("account");
  Predicate global = cb.equal(details.get("crm_id "), account.get("top_parent"));
  Predicate top = cb.equal(details.get("crm_id "), account.get("global_partner"));
  account.on(cb.or(global, top));

但是,它会创建查询

SELECT DISTINCT
    p.name
FROM
    partner p
        INNER JOIN
    detail d ON p.detail_id = d.id
        INNER JOIN
    account a ON d.account_id = a.id
        AND (d.crm_id = a.top_parent
        OR d.crm_id = a.global_partner)

注意查询中的 AND 运算符...我需要将其替换为 OR 运算符

我遇到的另一个用例

@Entity
public class Detail {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;
  
  @OneToMany(mappedBy = "detail", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
  private Set<Skill> skills;
}

我正在尝试使用规范生成下面的查询

order by (select count(s.detail_id) from skill s where detail.id = s.detail_id AND s.category is not null) desc

我用过下面的代码

cq.orderBy(cb.desc(cb.size(details.get("skills"))));

但是它生成的查询是

order by (select count(s.detail_id) from skill s where detail.id = s.detail_id) desc

请注意,我无法向 order by 子句添加额外的 AND

我相信你不能改变那个AND。 你能按以下方式更改查询吗

SELECT DISTINCT p.name
FROM partner p INNER JOIN detail d ON p.detail_id = d.id, account a
where d.account_id = a.id
OR d.crm_id = a.top_parent
OR d.crm_id = a.global_partner

并且 jpa 标准类似于

    Join<Partner, Detail> details = root.join("detail");
    Root<Account> account = criteria.from(Account.class);
    Predicate global = cb.equal(details.get("crm_id"), account.get("top_parent"));
    Predicate top = cb.equal(details.get("crm_id"), account.get("global_partner"));
    Predicate byId = cb.equal(details.get("account").get("id"), account.get("id"));
    Predicate or = cb.or(global, top, byId);
    criteria.where(or);