广告
返回顶部
首页 > 资讯 > 后端开发 > Python >jpa多条件查询重写Specification的toPredicate方法
  • 270
分享到

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

2024-04-02 19:04:59 270人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录Criteria查询基本概念Criteria查询基本对象的构建下面我们用两个示例代码来更深入的了解spring Data JPA支持JPA2.0的Criteria查询,相应的接口

spring Data JPA支持JPA2.0的Criteria查询,相应的接口是JpaSpecificationExecutor。

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

这个接口基本是围绕着Specification接口来定义的, Specification接口中只定义了如下一个方法:


Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);

要理解这个方法,以及正确的使用它,就需要对JPA2.0的Criteria查询有一个足够的熟悉和理解,因为这个方法的参数和返回值都是JPA标准里面定义的对象。

Criteria查询基本概念

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

  • CriteriaQuery接口:代表一个specific的顶层查询对象,它包含着查询的各个部分,比如:select 、from、where、group by、order by等 注意:CriteriaQuery对象只对实体类型或嵌入式类型的Criteria查询起作用
  • Root接口:代表Criteria查询的根对象,Criteria查询的查询根定义了实体类型,能为将来导航获得想要的结果,它与sql查询中的FROM子句类似

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

2:查询根实例能通过传入一个实体类型给 AbstractQuery.from方法获得。

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 .where 方法应用到CriteriaQuery 对象上
  • C:CriteriaBuilder也作为Predicate实例的工厂,通过调用CriteriaBuilder 的条件方( equalnotEqual, gt, ge,lt, le,between,like等)创建Predicate对象。
  • D:复合的Predicate 语句可以使用CriteriaBuilder的and, or andnot 方法构建。

构建简单的Predicate示例:


Predicate p1=cb.like(root.get(“name”).as(String.class), “%”+uqm.getName()+“%”);
Predicate p2=cb.equal(root.get("uuid").as(Integer.class), uqm.getUuid());
Predicate p3=cb.gt(root.get("age").as(Integer.class), uqm.getAge());

构建组合的Predicate示例:


Predicate p = cb.and(p3,cb.or(p1,p2));

下面我们用两个示例代码来更深入的了解

复杂条件多表查询


//需要查询的对象
public class Qfjbxxdz {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid.hex")
    private String id;
    @OneToOne
    @JoinColumn(name = "qfjbxx")
    private Qfjbxx qfjbxx; //关联表
    private String fzcc;
    private String fzccName;
    @ManyToOne
    @JoinColumn(name = "criminalInfo")
    private CriminalInfo criminalInfo;//关联表
    @Column(length=800)
    private String bz;
    //get/set......
}
//创建构造Specification的方法
//这里我传入两个条件参数因为与前段框架有关,你们写的时候具体自己业务自行决断
private Specification<Qfjbxxdz> getWhereClause(final JSONArray condetion,final jsONArray search) {
        return new Specification<Qfjbxxdz>() {
            @Override
            public Predicate toPredicate(Root<Qfjbxxdz> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicate = new ArrayList<>();
                Iterator<JSONObject> iterator = condetion.iterator();
                Predicate preP = null;
                while(iterator.hasNext()){
                    JSONObject jsonObject = iterator.next();
                    //注意:这里用的root.join 因为我们要用qfjbxx对象里的字段作为条件就必须这样做join方法有很多重载,使用的时候可以多根据自己业务决断
                    Predicate p1 = cb.equal(root.join("qfjbxx").get("id").as(String.class),jsonObject.get("fzId").toString());
                    Predicate p2 = cb.equal(root.get("fzcc").as(String.class),jsonObject.get("ccId").toString());
                    if(preP!=null){
                        preP = cb.or(preP,cb.and(p1,p2));
                    }else{
                        preP = cb.and(p1,p2);
                    }
                }
                JSONObject jsonSearch=(JSONObject) search.get(0);
                Predicate p3=null;
                if(null!=jsonSearch.get("xm")&&jsonSearch.get("xm").toString().length()>0){
                   p3=cb.like(root.join("criminalInfo").get("xm").as(String.class),"%"+jsonSearch.get("xm").toString()+"%");
                }
                Predicate p4=null;
                if(null!=jsonSearch.get("fzmc")&&jsonSearch.get("fzmc").toString().length()>0){
                    p4=cb.like(root.join("qfjbxx").get("fzmc").as(String.class),"%"+jsonSearch.get("fzmc").toString()+"%");
                }
                Predicate preA;
                if(null!=p3&&null!=p4){
                    Predicate  preS =cb.and(p3,p4);
                    preA =cb.and(preP,preS);
                }else if(null==p3&&null!=p4){
                    preA=cb.and(preP,p4);
                }else if(null!=p3&&null==p4){
                    preA=cb.and(preP,p3);
                }else{
                    preA=preP;
                }
                predicate.add(preA);
                Predicate[] pre = new Predicate[predicate.size()];
                query.where(predicate.toArray(pre));
                return query.getRestriction();
            }

编写DAO类或接口

dao类/接口 需继承


public interface JpaSpecificationExecutor<T> 

接口;

如果需要分页,还可继承


public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> 

JpaSpecificationExecutor 接口具有方法


    Page<T> findAll(Specification<T> spec, Pageable pageable);  //分页按条件查询  
    List<T> findAll(Specification<T> spec);    //不分页按条件查询 

方法。 我们可以在Service层调用这两个方法。

两个方法都具有 Specification spec 参数,用于设定查询条件。

Service 分页+多条件查询 调用示例:


studentInfoDao.findAll(new Specification<StudentInfo> () { 
   public Predicate toPredicate(Root<StudentInfo> root,  
     CriteriaQuery<?> query, CriteriaBuilder cb) {  
    Path<String> namePath = root.get("name");  
    Path<String> nicknamePath = root.get("nickname");  
      
    query.where(cb.like(namePath, "%李%"), cb.like(nicknamePath, "%王%")); //这里可以设置任意条查询条件 
    return null;  
   } 
  }, page); 
 } 

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

然后通过连接多个查询条件即可。 这种方式使用JPA的api设置了查询条件,所以不需要再返回查询条件Predicate给Spring Data Jpa,故最后return null;即可。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: jpa多条件查询重写Specification的toPredicate方法

本文链接: https://www.lsjlt.com/news/158043.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • jpa多条件查询重写Specification的toPredicate方法
    目录Criteria查询基本概念Criteria查询基本对象的构建下面我们用两个示例代码来更深入的了解Spring Data JPA支持JPA2.0的Criteria查询,相应的接口...
    99+
    2022-11-12
  • 详解Spring Data JPA动态条件查询的写法
    我们在使用SpringData JPA框架时,进行条件查询,如果是固定条件的查询,我们可以使用符合框架规则的自定义方法以及@Query注解实现。如果是查询条件是动态的,框架也提供了查询接口。JpaSpecificationExecutor...
    99+
    2023-05-31
    spring data jpa
  • mybatis collection 多条件查询的实现方法
    mybatis collection 多条件查询的实现方法 前言: 业务需要通过mybatis 查询返回嵌套集合,嫌多次查询太麻烦,用自带的高级查询解决问题,下边是代码,已测试通过。 说下自己的理解,就是一...
    99+
    2022-10-18
  • ORACLE多条件统计查询的简单方法
    前几天要做一个统计查询的功能,因为涉及多张表,多种条件的统计分析。一开始便想到了UNION和IF语句,然后写了1000多行代码,就为了查30条数据觉得不应该。 然后就开始百度,多种条件下的统计。然...
    99+
    2022-10-18
  • php查询多条数据的方法
    这篇文章主要介绍了php查询多条数据的方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。php查询多条数据的方法:首先创建一个PHP示例文件;然后创建PHP MySQL连接;...
    99+
    2023-06-14
  • 使用Spring Data JPA如何实现多条件的分页查询
    使用Spring Data JPA如何实现多条件的分页查询?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。话不多说,请看代码:public Map<String, Obje...
    99+
    2023-05-31
    spring 分页查询 dat
  • sql多条件组合查询的方法是什么
    在SQL中,可以使用AND或者OR运算符来组合多个条件查询。AND运算符用于同时满足多个条件的查询,而OR运算符用于满足其中一个条件...
    99+
    2023-08-21
    sql
  • lambdaQueryWrapper多条件嵌套查询方法是什么
    这篇文章主要讲解了“lambdaQueryWrapper多条件嵌套查询方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“lambdaQueryWrapper多条件嵌套查询方法是什么”吧...
    99+
    2023-06-26
  • mysql 带多个条件的查询方式
    mysql 带多个条件的查询 环境:mysql 5.7 当一个where语句中同时出现多个and 或者or时,需要将多个OR用小括号括起来再和AND进行“与”,或者将多个A...
    99+
    2022-11-12
  • jpa实现多对多的属性时查询的两种方法
    目录jpa多对多的属性查询第一:采用JPQL方式第二:采用specification 方法JPA,HQL多对多的查询语句Hql语句另外一种写法jpa多对多的属性查询 第一:采用JPQ...
    99+
    2022-11-12
  • mysql instr条件查询的实现方法
    这篇文章主要介绍“mysql instr条件查询的实现方法”,在日常操作中,相信很多人在mysql instr条件查询的实现方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”mysql instr条件查询的实...
    99+
    2023-06-20
  • MyBatisPlus QueryWrapper多条件查询及修改方法是什么
    这篇“MyBatisPlus QueryWrapper多条件查询及修改方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇...
    99+
    2023-07-02
  • 继承jpa Repository 写自定义方法查询的实例分析
    这篇文章给大家介绍继承jpa Repository 写自定义方法查询的实例分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。继承jpa Repository写自定义方法查询今天在写jpa查询的时候,...
    99+
    2023-06-21
  • MyBatis中多条件查询商品的三种方法及区别
    目录一、Sql语句设置多个参数有几种方式二、代码附上一、Sql语句设置多个参数有几种方式 1、散装参数:需要使用@Param标记Sql语句中占位符处的名称例如 #{name} ...
    99+
    2022-11-12
  • mysql中带多个条件的查询方式有哪些
    这篇文章将为大家详细讲解有关mysql中带多个条件的查询方式有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。mysql 带多个条件的查询环境:mysql 5.7当一个where语句中同时出现...
    99+
    2023-06-15
  • mysql查询每个表有多少条记录的方法
    mysql查询每个表有多少条记录的方法?这个问题可能是我们日常学习或工作经常见到的。希望通过这个问题能让你收获颇深。下面是小编给大家带来的参考内容,让我们一起来看看吧!mysql查询每个表有多少条记录的方法...
    99+
    2022-10-18
  • mybatis中的count()按条件查询的方法是什么
    这篇文章主要介绍“mybatis中的count()按条件查询的方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“mybatis中的count()按条件查询的方法是什么”文章能帮助大家解决问题。...
    99+
    2023-06-26
  • Django中常用的查询数据方法及查询对象的条件详解
    (1)常用的查询方法: 1.获取所有记录: s = User.objects.all() 2.获取第一条数据: s = User.objects.first() 3...
    99+
    2022-11-12
  • Oracle clob类型的字段作为查询条件的sql语句写法
    select × from INFORMATION   WHERE  dbms_lob.instr(CONTENT,'${content}')>0&nb...
    99+
    2022-10-18
  • vlookup函数多条件查找的方法是什么
    要使用VLOOKUP函数进行多条件查找,可以使用多个函数嵌套,或使用ARRAYFORMULA函数。1. 使用多个函数嵌套:- 首先,...
    99+
    2023-09-29
    vlookup
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作