You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Criteria Builder实现SQL多条件组合排除逻辑?

问题解答

你的Criteria Builder代码无法实现与目标SQL一致的逻辑,具体问题和修正方案如下:

原SQL逻辑解析

目标SQL的条件是:

NOT(request_type = 'SELF_SERVICE' and enquiry_status_id = 19)

它的含义是:排除所有同时满足request_type = 'SELF_SERVICE'且enquiry_status_id = 19的记录,根据德摩根定律,等价于:

request_type != 'SELF_SERVICE' OR enquiry_status_id != 19

你的代码存在的问题

你当前的代码构造的条件是:

cb.equal(enquiryRoot.get("requestType"), "SELF_SERVICE") 
AND 
cb.notEqual(enquiryRoot.get("status").get("id"), 19)

这表示筛选request_type = 'SELF_SERVICE'且enquiry_status_id != 19的记录,和原SQL的排除逻辑完全相反,范围完全不同。

正确的实现方式

有两种等价的写法可以匹配原SQL的逻辑:

写法一:直接使用cb.not()包裹原组合条件

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Enquiry> query = cb.createQuery(Enquiry.class);
Root<Enquiry> enquiryRoot = query.from(Enquiry.class);

// 构造原SQL中的内部条件:request_type = 'SELF_SERVICE' AND enquiry_status_id = 19
Predicate selfServiceAndStatus19 = cb.and(
    cb.equal(enquiryRoot.get("requestType"), "SELF_SERVICE"),
    cb.equal(enquiryRoot.get("status").get("id"), 19)
);

// 用NOT包裹该条件,实现原SQL的排除逻辑
query.where(cb.not(selfServiceAndStatus19));

写法二:利用德摩根定律转成OR条件

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Enquiry> query = cb.createQuery(Enquiry.class);
Root<Enquiry> enquiryRoot = query.from(Enquiry.class);

// 等价于 NOT(A AND B) = NOT A OR NOT B
Predicate notSelfService = cb.notEqual(enquiryRoot.get("requestType"), "SELF_SERVICE");
Predicate notStatus19 = cb.notEqual(enquiryRoot.get("status").get("id"), 19);

query.where(cb.or(notSelfService, notStatus19));

两种写法生成的SQL逻辑和你目标的查询完全一致,可以根据习惯选择使用。

内容的提问来源于stack exchange,提问作者Teong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 06:57:38