predicate

更新时间:2022-11-22 17:25:28 阅读: 评论:0


2022年11月22日发(作者:savvy)

jpa多条件查询重写Specification的toPredicate⽅法

⽬录

Criteria查询基本概念

Criteria查询基本对象的构建

下⾯我们⽤两个⽰例代码来更深⼊的了解

SpringDataJPA⽀持JPA2.0的Criteria查询,相应的接⼝是JpaSpecificationExecutor。

Criteria查询:是⼀种类型安全和更⾯向对象的查询。

这个接⼝基本是围绕着Specification接⼝来定义的,Specification接⼝中只定义了如下⼀个⽅法:

PredicatetoPredicate(Rootroot,CriteriaQuery<?>query,CriteriaBuildercb);

要理解这个⽅法,以及正确的使⽤它,就需要对JPA2.0的Criteria查询有⼀个⾜够的熟悉和理解,因为这个⽅法的参数和返回

值都是JPA标准⾥⾯定义的对象。

Criteria查询基本概念

Criteria查询是以元模型的概念为基础的,元模型是为具体持久化单元的受管实体定义的,这些实体可以是实体类,嵌⼊类或

者映射的⽗类。

CriteriaQuery接⼝:代表⼀个specific的顶层查询对象,它包含着查询的各个部分,⽐如:lect、from、where、group

by、orderby等注意:CriteriaQuery对象只对实体类型或嵌⼊式类型的Criteria查询起作⽤

Root接⼝:代表Criteria查询的根对象,Criteria查询的查询根定义了实体类型,能为将来导航获得想要的结果,它与

SQL查询中的FROM⼦句类似

1:Root实例是类型化的,且定义了查询的FROM⼦句中能够出现的类型。

2:查询根实例能通过传⼊⼀个实体类型给⽅法获得。

3:Criteria查询,可以有多个查询根。

4:AbstractQuery是CriteriaQuery接⼝的⽗类,它提供得到查询根的⽅法。CriteriaBuilder接⼝:⽤来构建CritiaQuery的构建

器对象Predicate:⼀个简单或复杂的谓词类型,其实就相当于条件或者是条件组合。

Criteria查询基本对象的构建

1:通过EntityManager的getCriteriaBuilder或EntityManagerFactory的getCriteriaBuilder⽅法可以得到CriteriaBuilder对象

2:通过调⽤CriteriaBuilder的createQuery或createTupleQuery⽅法可以获得CriteriaQuery的实例

3:通过调⽤CriteriaQuery的from⽅法可以获得Root实例过滤条件

A:过滤条件会被应⽤到SQL语句的FROM⼦句中。在criteria查询中,查询条件通过Predicate或Expression实例应⽤到

CriteriaQuery对象上。

B:这些条件使⽤⽅法应⽤到CriteriaQuery对象上

C:CriteriaBuilder也作为Predicate实例的⼯⼚,通过调⽤CriteriaBuilder的条件⽅(equalnotEqual,gt,ge,lt,

le,between,like等)创建Predicate对象。

D:复合的Predicate语句可以使⽤CriteriaBuilder的and,orandnot⽅法构建。

构建简单的Predicate⽰例:

Predicatep1=((“name”).as(),“%”+e()+“%”);

Predicatep2=(("uuid").as(),d());

Predicatep3=(("age").as(),());

构建组合的Predicate⽰例:

Predicatep=(p3,(p1,p2));

下⾯我们⽤两个⽰例代码来更深⼊的了解

复杂条件多表查询

//需要查询的对象

publicclassQfjbxxdz{

@Id

@GeneratedValue(generator="system-uuid")

@GenericGenerator(name="system-uuid",strategy="")

privateStringid;

@OneToOne

@JoinColumn(name="qfjbxx")

privateQfjbxxqfjbxx;//关联表

privateStringfzcc;

privateStringfzccName;

@ManyToOne

@JoinColumn(name="criminalInfo")

privateCriminalInfocriminalInfo;//关联表

@Column(length=800)

privateStringbz;

//get/t......

}

//创建构造Specification的⽅法

//这⾥我传⼊两个条件参数因为与前段框架有关,你们写的时候具体⾃⼰业务⾃⾏决断

privateSpecificationgetWhereClau(finalJSONArraycondetion,finalJSONArrayarch){

returnnewSpecification(){

@Override

publicPredicatetoPredicate(Rootroot,CriteriaQuery<?>query,CriteriaBuildercb){

Listpredicate=newArrayList<>();

Iteratoriterator=or();

PredicatepreP=null;

while(t()){

JSONObjectjsonObject=();

//注意:这⾥⽤的因为我们要⽤qfjbxx对象⾥的字段作为条件就必须这样做join⽅法有很多重载,使⽤的时候可以多根据⾃⼰业务决断

Predicatep1=(("qfjbxx").get("id").as(),("fzId").toString());

Predicatep2=(("fzcc").as(),("ccId").toString());

if(preP!=null){

preP=(preP,(p1,p2));

}el{

preP=(p1,p2);

}

}

JSONObjectjsonSearch=(JSONObject)(0);

Predicatep3=null;

if(null!=("xm")&&("xm").toString().length()>0){

p3=(("criminalInfo").get("xm").as(),"%"+("xm").toString()+"%");

}

Predicatep4=null;

if(null!=("fzmc")&&("fzmc").toString().length()>0){

p4=(("qfjbxx").get("fzmc").as(),"%"+("fzmc").toString()+"%");

}

PredicatepreA;

if(null!=p3&&null!=p4){

PredicatepreS=(p3,p4);

preA=(preP,preS);

}elif(null==p3&&null!=p4){

preA=(preP,p4);

}elif(null!=p3&&null==p4){

preA=(preP,p3);

}el{

preA=preP;

}

(preA);

Predicate[]pre=newPredicate[()];

(y(pre));

triction();

}

编写DAO类或接⼝

dao类/接⼝需继承

publicinterfaceJpaSpecificationExecutor

接⼝;

如果需要分页,还可继承

publicinterfacePagingAndSortingRepositoryextendsCrudRepository

JpaSpecificationExecutor接⼝具有⽅法

PagefindAll(Specificationspec,Pageablepageable);//分页按条件查询

ListfindAll(Specificationspec);//不分页按条件查询

⽅法。我们可以在Service层调⽤这两个⽅法。

两个⽅法都具有Specificationspec参数,⽤于设定查询条件。

Service分页+多条件查询调⽤⽰例:

l(newSpecification(){

publicPredicatetoPredicate(Rootroot,

CriteriaQuery<?>query,CriteriaBuildercb){

PathnamePath=("name");

PathnicknamePath=("nickname");

/**

*连接查询条件,不定参数,可以连接0..N个查询条件

*/

((namePath,"%李%"),(nicknamePath,"%王%"));//这⾥可以设置任意条查询条件

returnnull;

}

},page);

}

这⾥通过CriteriaBuilder的like⽅法创建了两个查询条件,姓名(name)字段必须包含“李”,昵称(nickname)字段必须包

含“王”。

然后通过连接多个查询条件即可。这种⽅式使⽤JPA的API设置了查询条件,所以不需要再返回查询条件Predicate给Spring

DataJpa,故最后returnnull;即可。

以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。

本文发布于:2022-11-22 17:25:28,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/90/509.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:sleepwalk
下一篇:rook
标签:predicate
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图