使用Spring-data-jpa执行嵌套查询时,语句中括号位置不正确

新手上路,请多包涵

使用Spring-data-jpa执行嵌套查询时,语句中括号位置不正确,相关代码如下:

Specification<ProjectVO> specification = new Specification<ProjectVO>() {
            
            private static final long serialVersionUID = -8267625374879507726L;

            public Predicate toPredicate(Root<ProjectVO> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                
                if(!StringUtils.isEmpty(key)) {
                    predicates.add(cb.or(
                            cb.like(root.<String>get(ProjectTab.H_NAME), "%" + key + "%"), 
                            cb.like(root.<String>get(ProjectTab.H_CUSTOMER).get(CustomerTab.H_NICKNAME), "%" + key + "%") 
                            ));
                }
                
                Join<ProjectVO, CustomerVO> customerJoin = root.join(ProjectTab.H_CUSTOMER, JoinType.LEFT);
                predicates.add(cb.equal(root.<Integer>get(ProjectTab.H_TYPE), Project.TYPE_LAWSUIT));
                
                if(service != null) {
                    predicates.add(cb.equal(root.<ServiceVO>get(ProjectTab.H_SERVICE), service));
                }
                
                if(projectStatus != null && projectStatus != 0) {
                    predicates.add(cb.equal(customerJoin.<StaffVO>get(CustomerTab.H_SALESMAN), salesman));
                    predicates.add(cb.equal(root.<Integer>get(ProjectTab.H_PROJECT_STATUS), projectStatus));
                }else {
                    Predicate coursePredicate = cb.and(
                            cb.isNull(customerJoin.<StaffVO>get(CustomerTab.H_SALESMAN)),
                            cb.equal(root.<Integer>get(ProjectTab.H_PROJECT_STATUS), Project.PROJECT_STATUS_EXAMINE)
                            );
                    coursePredicate = cb.or(
                            coursePredicate, 
                            cb.equal(customerJoin.<StaffVO>get(CustomerTab.H_SALESMAN), salesman)
                            );
                    predicates.add(coursePredicate);
                }
                
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };

如上代码,期望SQL的查询条件按如下方式执行:

 select * from t_project projectvo0_ 
 left outer join
        t_user_customer customervo1_ 
            on projectvo0_.c_customer=customervo1_.c_id 
    where
        projectvo0_.c_type=1 
        and (
            (
                customervo1_.c_salesman is null
                and projectvo0_.c_project_status=1 
            ) 
            or customervo1_.c_salesman=?
        ) 
    order by
        projectvo0_.c_modify_time desc limit ?

但实际却是

select * from t_project projectvo0_ 
left outer join
        t_user_customer customervo1_ 
            on projectvo0_.c_customer=customervo1_.c_id 
    where
        projectvo0_.c_type=1 
        and (
            (
                customervo1_.c_salesman is null
            ) 
            and projectvo0_.c_project_status=1 
            or customervo1_.c_salesman=?
        ) 
    order by
        projectvo0_.c_modify_time desc limit ?

在where语句中的括号位置没有对,请问如何正确的完成这个查询操作的书写呢?

阅读 6.8k
3 个回答
新手上路,请多包涵

请问搞定了吗,我也遇到这个问题?求指导

新手上路,请多包涵

没有搞定。。。。难受

新手上路,请多包涵

同一问题,(A AND B) OR C,变成了 A AND B OR C...
仔细探究后,这是hibernate的优化,并不是会缺括号,AND是优先于OR的,所以这里的括号是没必要的

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进