JPA组装查询条件

本文介绍了使用JPA进行查询的几种方式,包括方法参数的灵活性、简单的查询操作、等值判断、不等于判断、大于判断、between操作、like模糊查询和in条件查询。详细展示了各种查询条件的示例及结果解析,特别指出null值在不同条件下的处理方式。

查询示例

    public Page<Student> queryList(StudentVO studentVO){
        int page = 1;
        int size = 20;
        // 创建Pageable对象,页数从0开始查询
        PageRequest pageRequest = PageRequest.of(page-1, size);
        // 拉姆达表达式
        Specification<Student> userSpecification = (root, query, criteriaBuilder)->buildQueryParam(studentVO, root, criteriaBuilder);
        Page<Student> all = studentDao.findAll(userSpecification, pageRequest);
        return all;
    }

查询的方法:

   private Predicate buildQueryParam(StudentVO studentVO, Root<Student> root, CriteriaBuilder criteriaBuilder){
       List<Predicate> list = new ArrayList<>();
       // 拼条件
       if(studentVO.getAge() != null){
           list.add(criteriaBuilder.equal(root.get("age"), studentVO.getAge()));
       }
       // 转换为Predicate[]
       Predicate[] predicates = list.toArray(new Predicate[]{});
       return criteriaBuilder.and(predicates);
   }

相关的Dao:

@Repository
public interface StudentDao extends JpaRepository<Student, String>, JpaSpecificationExecutor<Student> {
}

注意

方法入参可以交换位置

    Specification<Student> userSpecification = (root, query, criteriaBuilder)->buildQueryParam(root, criteriaBuilder, studentVO);

查询的方法:

   private Predicate buildQueryParam(Root<Student> root, CriteriaBuilder criteriaBuilder, StudentVO studentVO){
   }

简单查询

在这里插入图片描述

判断条件

演示数据
在这里插入图片描述

INSERT INTO `jpa_study`.`student`(`id`, `name`, `age`, `gender`, `create_time`) VALUES ('a90bcd22f811a', '张三', 18, 0, '2022-11-24 16:14:34');
INSERT INTO `jpa_study`.`student`(`id`, `name`, `age`, `gender`, `create_time`) VALUES ('a90bcd22f811b', '李四', 23, 1, '2022-11-24 16:53:02');
INSERT INTO `jpa_study`.`student`(`id`, `name`, `age`, `gender`, `create_time`) VALUES ('a90bcd22f811c', '王五一', 19, 0, '2022-12-13 11:10:38');
INSERT INTO `jpa_study`.`student`(`id`, `name`, `age`, `gender`, `create_time`) VALUES ('a90bcd22f811d', '赵六一', 19, 1, '2022-11-29 11:11:00');
INSERT INTO `jpa_study`.`student`(`id`, `name`, `age`, `gender`, `create_time`) VALUES ('a90bcd22f811e', '刘七', 20, 0, '2022-12-07 11:11:32');
INSERT INTO `jpa_study`.`student`(`id`, `name`, `age`, `gender`, `create_time`) VALUES ('a90bcd22f811f', '孙子', NULL, 1, '2022-12-01 11:12:27');
INSERT INTO `jpa_study`.`student`(`id`, `name`, `age`, `gender`, `create_time`) VALUES ('a90bcd22f811g', '周一一', NULL, 1, '2022-12-05 11:15:00');

等于

需求:获取age等于19的所有数据

        // 等于
        if(studentVO.getAge() != null){
            list.add(criteriaBuilder.equal(root.get("age"), studentVO.getAge()));
        }

结果:
在这里插入图片描述

不等于

需求:获取age不等于19的所有数据

        // 不等于,注意不等于只在有数据的记录内判断,如果字段为null,这不是不等于
        if(studentVO.getAge() != null){
            list.add(criteriaBuilder.notEqual(root.get("age"), studentVO.getAge()));
        }

结果:
在这里插入图片描述

之所以没有“孙子、周一一”,是因为这两条数据的age为null,null不是不等于19。
注意 不等于某个具体数值时不计算null,即如果字段为null,该记录不是不等于某个具体数值。

大于

需求:获取age大于19的所有数据

        if(studentVO.getAge() != null){
            list.add(criteriaBuilder.greaterThan(root.get("age"), studentVO.getAge()));
        }

结果:
在这里插入图片描述

注意 null同样不计算在内

between

需求:获取年龄在19,20之间的所有数据,包括19和20

        if(studentVO.getAge() != null){
            list.add(criteriaBuilder.between(root.get("age"), studentVO.getAge(),20));
        }

结果:
在这里插入图片描述

注意 between是全闭区间,包括头尾数据。

like

需求:name模糊查询“一”

        if(studentVO.getName() != null){
            list.add(criteriaBuilder.like(root.get("name"),"%"+studentVO.getName()+"%"));
        }

结果:
在这里插入图片描述

in

需求:name in(“张三”、“李四”)

        if(studentVO.getName() != null){
            CriteriaBuilder.In<Object> inNames = criteriaBuilder.in(root.get("name"));
            List<String> nameList = new ArrayList<>();
            nameList.add("张三");
            nameList.add("李四");
            for (String s : nameList) {
                inNames.value(s);
            }
            list.add(inNames);
        }

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值