如何在Spring JPA Specification的WHERE子句中添加括号
Spring JPA Specification 实现带括号的WHERE条件
需求场景
需要实现两种带括号逻辑的WHERE条件:
WHERE cond1 AND (cond2 OR cond3)WHERE (cond1 AND cond2) OR cond3
解决方案代码
1. 实现 WHERE cond1 AND (cond2 OR cond3)
Specification<DocRecord> cond1AndCond2OrCond3Spec = (root, query, cb) -> { // 定义单个条件 Predicate cond1 = cb.lessThanOrEqualTo(root.get("updatedAt"), new Timestamp(now.getTimeInMillis())); Predicate cond2 = cb.lessThan(root.get("attemptCount"), 3); Predicate cond3 = cb.equal(root.get("attemptCount"), 0); // 先构造cond2 OR cond3的嵌套条件,再与cond1做AND return cb.and(cond1, cb.or(cond2, cond3)); };
生成的SQL会包含括号:
WHERE docrecord0_.updated_at <= ? AND (docrecord0_.attempt_count < 3 OR docrecord0_.attempt_count = 0)
2. 实现 WHERE (cond1 AND cond2) OR cond3
Specification<DocRecord> cond1AndCond2OrCond3Spec = (root, query, cb) -> { // 定义单个条件 Predicate cond1 = cb.lessThanOrEqualTo(root.get("updatedAt"), new Timestamp(now.getTimeInMillis())); Predicate cond2 = cb.lessThan(root.get("attemptCount"), 3); Predicate cond3 = cb.equal(root.get("attemptCount"), 0); // 先构造cond1 AND cond2的嵌套条件,再与cond3做OR Predicate andGroup = cb.and(cond1, cond2); return cb.or(andGroup, cond3); };
生成的SQL会包含括号:
WHERE (docrecord0_.updated_at <= ? AND docrecord0_.attempt_count < 3) OR docrecord0_.attempt_count = 0
补充说明
你之前的代码逻辑本身是正确的,只是SQL中AND优先级高于OR,部分JPA实现(如Hibernate)会省略不影响逻辑的括号。通过显式将组合条件赋值给单独的Predicate变量,可以让JPA明确生成带括号的SQL结构,同时代码可读性也更强。
内容的提问来源于stack exchange,提问作者Sidaoui Majdi
相关产品推荐
相关产品推荐

