详解Spring Data JPA动态条件查询的写法
我们在使用SpringDataJPA框架时,进行条件查询,如果是固定条件的查询,我们可以使用符合框架规则的自定义方法以及@Query注解实现。
如果是查询条件是动态的,框架也提供了查询接口。
JpaSpecificationExecutor
和其他接口使用方式一样,只需要在你的Dao接口继承即可(官网代码)。
publicinterfaceCustomerRepositoryextendsCrudRepository,JpaSpecificationExecutor{ … }
JpaSpecificationExecutor提供很多条件查询方法。
publicinterfaceJpaSpecificationExecutor{ TfindOne(Specification var1); List findAll(Specification var1); Page findAll(Specification var1,Pageablevar2); List findAll(Specification var1,Sortvar2); longcount(Specification var1); }
比如方法:
ListfindAll(Specification var1);
就可以查找出符合条件的所有数据,如果你的框架使用的是前段分页的技术,那么这个方法就挺简便的。
那么这个方法该如何使用呢?我们看到它需要的参数是一个
org.springframework.data.jpa.domain.Specification
对象。那我们就创建这个对象先看看。
Specificationspecification=newSpecification(){
@Override
publicPredicatetoPredicate(Rootroot,CriteriaQuerycriteriaQuery,CriteriaBuildercriteriaBuilder){
returnnull;
}
}
IDE自动生成了要重写的方法toPredicate。
root参数是我们用来对应实体的信息的。criteriaBuilder可以帮助我们制作查询信息。
/** *Aroottypeinthefromclause. *Queryrootsalwaysreferenceentities. * *@paramtheentitytypereferencedbytheroot *@sinceJavaPersistence2.0 */ publicinterfaceRoot extendsFrom {...}
/** *Usedtoconstructcriteriaqueries,compoundselections, *expressions,predicates,orderings. * *Notethat
PredicateisusedinsteadofExpression<Boolean>*inthisAPIinordertoworkaroundthefactthatJava *genericsarenotcompatiblewithvarags. * *@sinceJavaPersistence2.0 */ publicinterfaceCriteriaBuilder{...}
CriteriaBuilder对象里有很多条件方法,比如制定条件:某条数据的创建日期小于今天。
criteriaBuilder.lessThan(root.get("createDate"),today)
该方法返回的对象类型是Predicate。正是toPredicate需要返回的值。
如果有多个条件,我们就可以创建一个Predicate集合,最后用CriteriaBuilder的and和or方法进行组合,得到最后的Predicate对象。
/** *Createaconjunctionofthegivenrestrictionpredicates. *Aconjunctionofzeropredicatesistrue. * *@paramrestrictionszeroormorerestrictionpredicates * *@returnandpredicate */ Predicateand(Predicate...restrictions);
/** *Createadisjunctionofthegivenrestrictionpredicates. *Adisjunctionofzeropredicatesisfalse. * *@paramrestrictionszeroormorerestrictionpredicates * *@returnorpredicate */ Predicateor(Predicate...restrictions);
示例:
publicListfindByCondition(DateminDate,DatemaxDate,Stringnickname){ List resultList=null; SpecificationquerySpecifi=newSpecification (){ @Override publicPredicatetoPredicate(Root root,CriteriaQuery>criteriaQuery,CriteriaBuildercriteriaBuilder){ List predicates=newArrayList<>(); if(null!=minDate){ predicates.add(criteriaBuilder.greaterThan(root.get("subscribeTime"),minDate)); } if(null!=maxDate){ predicates.add(criteriaBuilder.lessThan(root.get("subscribeTime"),maxDate)); } if(null!=nickname){ predicates.add(criteriaBuilder.like(root.get("nickname"),"%"+nickname+"%")); } returncriteriaBuilder.and(predicates.toArray(newPredicate[predicates.size()])); } }; resultList=this.weChatGzUserInfoRepository.findAll(querySpecifi); returnresultList; }
and到一起的话所有条件就是且关系,or就是或关系了。
其实也是在StackOverflow上看到的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。