文章目录

  • 1. Jpa模糊查询学习笔记一:springBoot+jpa实现多条件模糊查询
  • 1.1. 扩展知识
  • 1.2. jpa多条件查询重写Specification的toPredicate方法
  • 1.3. toPredicate()方法的三个参数:Root \


1. Jpa模糊查询学习笔记一:springBoot+jpa实现多条件模糊查询

1.1. 扩展知识
  1. 匿名内部类:
  2. 匿名内部类:
  3. Predicate方法:
  4. list.toArray§:
1.2. jpa多条件查询重写Specification的toPredicate方法
  1. jpa的Criteria查询的相应接口是JpaSpecificationExecutor,也就是说如果dao层要使用jpa的查询功能,就要先继承该接口
  2. Criteria查询:是一种类型安全并且面向对象的一种查询功能。JpaSpecificationExecutor接口基本围绕着Specification接口来定义的,Specification接口只定义了一个方法。即:toPredicate()方法。
public Predicate toPredicate(Root<DevWarnPo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder)
1.3. toPredicate()方法的三个参数:Root <T> root, CriteriaQuery<?> criteriaQuery , CriteriaBuilder criteriaBuilder
  1. CriteriaQuery<?> criteriaQuery :这是一个面向对象查询,代表的是Specific的顶层查询对象,它包含查询的各个部分:select,from,where,group by, order by等,不过它是一个面向对象的查询方式,只对实体类型,嵌入式类型的Criteria查询起作用。
  2. Root<T> root :代表要查询的对象,也就是实体类型,实体类型好比sql语句中的from后的表。传入实体类型后,会被CriteriaQuery的父类AbstractQuery.from将实体类型传入。
  3. CriterBuilder criteriaBuilder:用来构建CriteriaQuery的构建器对象Predicate(谓语),即:一个简单或者复杂的谓语类型,相当于条件或者多条件集合。
  4. Predicate:就是多条件查询中的条件,可以通过List<Predicate> 实现多个条件操作。
1.4. Criteria查询对象的构建
  1. 通过EntityManager的getCriteriaBuilder或EntityManagerFactory的getCriteriaBuilder方法可以得到CriteriaBuilder对象。
  2. 通过调用CriteriaBuilder的createQuery或createTupleQuery方法可以获得CriteriaQuery的实例。
  3. 上面这两个是对三个参数的赋值操作。
  4. 除此之外还要对Predicate这个多条件内容进行赋值,是通过第三个参数CriteriaBuilder实现的。
  • 过滤条件会被应用到SQL语句的FROM子句中。在criteria 查询中,查询条件通过Predicate或Expression实例应用到CriteriaQuery对象上。
  • 这些条件使用 CriteriaQuery .where 方法应用到CriteriaQuery 对象上
  • CriteriaBuilder也作为Predicate实例的工厂,通过调用CriteriaBuilder 的条件方( equalnotEqual, gt, ge,lt, le,between,like等)创建Predicate对象。
  • 复合的Predicate 语句可以使用CriteriaBuilder的and, or andnot 方法构建。
1.5. 多条件查询案例
  1. 调用dao层,并创建查询方法,还要有分页机制。
  • new Specification<DevWarnPo> 这是一个接口,相当于匿名内部类,实现了改接口的方法。toPredicate();
  • dao层一定要继承JpaSpecificationExecutor接口。
  • 注意尖括号里的类型。
Page<DevWarnPo> devWarnPoPage = devWarnDao.findAll(new Specification<DevWarnPo>() {
  1. 重写Specification方法,只有一个toPredicate()
  • Root是查询对象,CriteriaQuery()是生成查询语句。CriteriaBuilder是进行给多条件赋值和设置like等条件的对象引用。
public Predicate toPredicate(Root<DevWarnPo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  1. 设置多条件
  • 设置where是CriteriaQuery对象的事,设置条件是CriteriaBuilder的事。
if(org.apache.commons.lang.StringUtils.isNotEmpty(devWarnModel.getDevWarnType())){
    list.add(criteriaBuilder.like(root.get("devWarnType").as(String.class), "%"+ devWarnModel.getDevWarnType().trim().replaceAll("/","//").replaceAll("_","/_").replaceAll("%","/%")+"%",'/'));
}
  1. 添加到CriteriaBuilder中,进行返回条件Predicate
Predicate[] p = new Predicate[list.size()];
return criteriaBuilder.and(list.toArray(p));
1.6. 源码
@Override
public Result findAllDevWarn(DevWarnModel devWarnModel) {
    Pageable pageable = PageRequest.of(devWarnModel.getPageIndex(), devWarnModel.getPageSize());
    Page<DevWarnPo> devWarnPoPage = devWarnDao.findAll(new Specification<DevWarnPo>() {
        @Override
        public Predicate toPredicate(Root<DevWarnPo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
            List<Predicate> list = new ArrayList<Predicate>();
            if(org.apache.commons.lang.StringUtils.isNotEmpty(devWarnModel.getDevWarnType())){
                list.add(criteriaBuilder.like(root.get("devWarnType").as(String.class), "%"+ devWarnModel.getDevWarnType().trim().replaceAll("/","//").replaceAll("_","/_").replaceAll("%","/%")+"%",'/'));
            }
            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        }
    },pageable);
    return Result.success(devWarnPoPage);
}