JPA查询or和and形式分页查询实现!

JPA查询or和and形式分页查询实现!

jpa分页查询不能完成or查询并且自动分页,该实例就是实现jpa的or和and查询并且自动分页的格式!

一、为什么需要使用该技术?

实现or和and类型的查询原生的sql语句如下:

select * from 表名(叫NB表) where 字段1 = 185 and (字段2(开始日期) between '2023-06-05 00:00:00' and '2023-06-06 00:00:00' ) or (字段3(结束日期) between '2023-06-05 00:00:00' and '2023-06-06 00:00:00' and 字段4 = true);

这样的sql实现了查询NB表,字段1等于185,开始日期在2023-06-05 00:00:00和2023-06-06 00:00:00这个区间内 ”或 “ 字段4等于真 “且” 结束日期 也在2023-06-05 00:00:00和2023-06-06 00:00:00这个区间内数据!原生的sql能够实现查询,但是无法实现分页,所以需要使用JPA复杂查询or和and连用代码实现!

二、代码实现

1.代码如下:

1.创建实体类:
在这里插入图片描述
实体类里面红色圈起来的部分是关联的另一张schoolDorm表中的信息!(ManyToOne有兴趣的可以去可以下!)

2.创建controller!
controller里面只是做了一个简单的引用!不做赘述了!
在这里插入图片描述
一个接收对象,一个分页表示加一个service层方法的引用!

3.创建service层,代码实现:
主要代码如下 可以直接用:

    public Map<String,Object> queryAllWithPageable(NbUploadExceptionQueryCriteria res, Pageable pageable) {
        //代码实现JPA复杂的or和and查询!
        Specification<NbUploadException> specification = (root, query, cb) -> {
            //1.判断必填条件不能为空!为空直接返回null
            if(res.getUserId()==null && res.getSchoolId() == null){
                return (javax.persistence.criteria.Predicate) PageUtil.toPage(null);
            }
            //2.统一格式,可以直接照抄
            List<Predicate> predicates = new ArrayList<>();
            //3.这里就是or连接,createTime在BeginTime和EndTime之间的 “或”resolveTime在BeginTime和EndTime之间 “且” isOK等于true
            predicates.add(cb.or(cb.between(root.get("createTime"), res.getBeginTime(),res.getEndTime()),
                    cb.and(cb.equal(root.get("isOk"), true),cb.between(root.get("resolveTime"), res.getBeginTime(),res.getEndTime()))));

            // 4.使用左连接查询(关联表作为条件需要使用到)
            Join<NbUploadException, SchoolDorm> join = root.join("schoolDorm", JoinType.LEFT);
            //5.添加姓名条件
            if (res.getSchoolId() != null) {
                //root相当于操作本张表的数据!
                predicates.add(cb.equal(root.get("schoolId"), res.getSchoolId()));
            }
            if (res.getFloor() != null) {
                //join是关联表的数据!
                predicates.add(cb.equal(join.get("floor"), res.getFloor()));
            }
            if (res.getDormNum() != null) {
                predicates.add(cb.equal(join.get("dormNum"), res.getDormNum()));
            }
            if (res.getImei() != null) {
                predicates.add(cb.equal(root.get("imei"), res.getImei()));
            }
            return cb.and(predicates.toArray(new javax.persistence.criteria.Predicate[predicates.size()]));
        };
        //6.这里的格式是根据自己需求去转换的 我这里需要的是DTO的形式!
        return PageUtil.toPage(NbUploadExceptionRepository.findAll(specification, pageable).map(NbUploadExceptionMapper::toDto));
    }

代码中3的位置就相当于sql这句:

select * from 表名(叫NB表) where 字段1 = 185 and (字段2(开始日期) between '2023-06-05 00:00:00' and '2023-06-06 00:00:00' ) or (字段3(结束日期) between '2023-06-05 00:00:00' and '2023-06-06 00:00:00' and 字段4 = true);

总结

我觉得这个方法还是非常的有用!后面的开发任务总会遇到的!也让大部分的开发变得简单也不局限于JPA封装好的格式了,很nice ,希望本次分享对你有用!共同进步!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值