jpa多条件查询重写Specification的toPredicate⽅法
⽬录
Criteria查询基本概念
Criteria查询基本对象的构建
下⾯我们⽤两个⽰例代码来更深⼊的了解
SpringDataJPA⽀持JPA2.0的Criteria查询,相应的接⼝是JpaSpecificationExecutor。
Criteria查询:是⼀种类型安全和更⾯向对象的查询。
这个接⼝基本是围绕着Specification接⼝来定义的,Specification接⼝中只定义了如下⼀个⽅法:
PredicatetoPredicate(Root
要理解这个⽅法,以及正确的使⽤它,就需要对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的⽅法
//这⾥我传⼊两个条件参数因为与前段框架有关,你们写的时候具体⾃⼰业务⾃⾏决断
privateSpecification
returnnewSpecification
@Override
publicPredicatetoPredicate(Root
List
Iterator
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
接⼝;
如果需要分页,还可继承
publicinterfacePagingAndSortingRepository
JpaSpecificationExecutor接⼝具有⽅法
Page
List
⽅法。我们可以在Service层调⽤这两个⽅法。
两个⽅法都具有Specificationspec参数,⽤于设定查询条件。
Service分页+多条件查询调⽤⽰例:
l(newSpecification
publicPredicatetoPredicate(Root
CriteriaQuery<?>query,CriteriaBuildercb){
Path
Path
/**
*连接查询条件,不定参数,可以连接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小时内删除。
留言与评论(共有 0 条评论) |