[JPA复习 ] Specification多条件查询

下面的文字結合代码阅读:

  1. CriteriaBuilder 安全查询创建工厂
  2. CriteriaBuilder 安全查询创建工厂,,创建CriteriaQuery,创建查询具体具体条件Predicate 等。
    CriteriaBuilder是一个工厂对象,安全查询的开始.用于构建JPA安全查询.可以从EntityManager 或
    EntityManagerFactory类中获得CriteriaBuilder。

CriteriaQuery 安全查询 语句

  1. 它通过调用 CriteriaBuilder, createQuery 或CriteriaBuilder.createTupleQuery
    获得。 CriteriaBuilder就像CriteriaQuery 的工厂一样。
    CriteriaQuery对象必须在实体类型或嵌入式类型上的Criteria 查询上起作用。

    在CriteriaBuilder底层 发现有 CriteriaQuery方法;
    CriteriaBuilder 安全查询创建工厂,,创建CriteriaQuery,
    在这里插入图片描述

Predicate 讲解条件:

  1. 过滤条件应用到SQL语句的FROM子句中。

    在criteria 查询中,查询条件通过Predicate 或Expression 实例应用到CriteriaQuery 对象上。

    这些条件使用 CriteriaQuery .where 方法应用到CriteriaQuery 对象上。

    Predicate 实例也可以用Expression 实例的 isNull, isNotNull 和
    in方法获得,复合的Predicate 语句可以使用CriteriaBuilder的and, or andnot 方法构建。

    CriteriaBuilder 也是作为Predicate 实例的工厂,Predicate 对象通过调用CriteriaBuilder
    的条件方法( equal,notEqual, gt, ge,lt, le,between,like等)创建。

    这些条件使用 CriteriaQuery.where 方法应用到CriteriaQuery对象上。

Root 讲解含义:
Root 定义查询的From子句中能出现的类型

criteriaQuery查询的查询根定义了实体类型,能为将来导航获得想要的结果,它与SQL查询中的FROM子句类似。

Root实例也是类型化的,且定义了查询的FROM子句中能够出现的类型。
查询根实例能通过传入一个实体类型给 AbstractQuery.from方法获得。
CriteriaQuery继承AbstractQuery里的方法
CriteriaQuery底层:
CriteriaQuery继承 AbstractQuery

在这里插入图片描述
AbstractQuery底层:
CriteriaQuery和它一样 都是对
在这里插入图片描述
CommonAbstractCriteria底层:

在这里插入图片描述

在这里插入图片描述

criteriaQuery查询,可以有多个查询根。
Employee实体的查询根对象可以用以下的语法获得 :
Root cardManagement= criteriaQuery.from(CardManagement.class); 这里的


  1. Root:查询哪个表 CriteriaQuery:查询哪些字段,排序是什么
    CriteriaBuilder:字段之间是什么关系,如何生成一个查询条件,每一个查询条件都是什么方式
    Predicate(Expression):单独每一条查询条件的详细描述,和CriteriaBuilder接口的各个查询条件拼接

如以下代码:

   /**
     * 动态多条件查询 :这里是根据卡管理表的 客户姓名和身份证模糊  查询
     * @param name
     * @param peopleId
     * @return
     */
    @Override
    public Long findByNameAndPid(String name, String peopleId) {
        System.out.println("打印入參信息"+name+"==="+peopleId);
         Long resultList = null;
        Specification querySpecifi = new Specification<CardManagement>() {
            @Override
            public Predicate toPredicate(Root<CardManagement> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if(null != name){
                    predicates.add(criteriaBuilder.like(root.get("name"), "%"+name+"%"));
                }
                if(null != peopleId){
                    predicates.add(criteriaBuilder.like(root.get("peopleId"), "%"+peopleId+"%"));
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        resultList = this.cardManagementRepository.count(querySpecifi);
        System.out.println("打印輸出信息"+resultList);
        return resultList;
    }




1:root 先封装的对应 对象,
2:root 对象名称.get 获取到对应对象里的属性值;
3:criteriaBuilder.like 模糊查询,字段通过这个方法被predicates.add 以数组的形式保存
4:criteriaBuilder.and 拼接 predicates 里存储的多个 多条件查询
select * from 表名 where 条件=? and 条件=?

在这里插入图片描述


    @RequestMapping(value = "/findByCondition",method = RequestMethod.POST)
    @ApiOperation("查询")
    public Optional<CardManagement>  findByCondition(String name){
        System.out.println("55"+name);
       Optional<CardManagement> resultList = null;
        Specification querySpecifi = new Specification<CardManagement>() {
            @Override
            public Predicate toPredicate(Root<CardManagement> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
// if(null != name){
//  predicates.add(criteriaBuilder.greaterThan(root.get("name"), name));
// }
// if(null != maxDate){
//  predicates.add(criteriaBuilder.lessThan(root.get("subscribeTime"), maxDate));
//  }
                if(null != name){
                    predicates.add(criteriaBuilder.like(root.get("name"), "%"+name+"%"));
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        resultList = this.cardManagementRepository.findOne(querySpecifi);
    return resultList;
   }


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: JPA Specification是一种用于构建动态查询的API,可以用于多表查询。通过使用Specification,可以根据不同的查询条件动态地构建查询语句,从而实现多表查询。在多表查询中,需要使用Join操作将多个表连接起来,然后根据查询条件进行过滤和排序。使用JPA Specification可以方便地构建这样的查询语句,从而提高查询效率和灵活性。 ### 回答2: JPA Specification是一种规范,允许我们在不暴露数据访问层的情况下执行动态查询。当需要在多张表中查询数据时,JPA Specification同样适用。在多表查询时,我们可以使用Join方式连接多张表。 一个简单的例子是,我们需要根据用户和订单表查询某个用户的订单记录。我们可以使用JPA Specification的Join方法把用户表和订单表连接起来,然后通过where条件来限定用户ID。具体代码如下: ```java public static Specification<Order> findByUserId(Long userId) { return (root, query, cb) -> { Join<Order, User> userJoin = root.join("user", JoinType.LEFT); //建立join关系 return cb.equal(userJoin.get("id"), userId); //指定where条件 }; } ``` 以上代码中,我们通过root.join方法建立了user表和order表的Join关系,然后通过cb.equal方法指定了where条件,即查询用户ID等于指定ID的订单记录。 除此之外,我们还可以进行多表嵌套查询,如查询一个用户的所有订单信息和订单的商品信息。这时,我们需要建立三张表之间的Join关系,并指定查询条件。具体代码如下: ```java public static Specification<Order> findUserOrderWithProduct(Long userId) { return (root, query, cb) -> { Join<Order, User> userJoin = root.join("user", JoinType.LEFT); //建立user表和order表的Join关系 Join<Order, Product> productJoin = root.join("product", JoinType.LEFT); //建立product表和order表的Join关系 query.distinct(true); //去重 return cb.and( cb.equal(userJoin.get("id"), userId), //指定用户ID cb.equal(root.get("status"), Order.Status.COMPLETED), //指定订单状态 cb.equal(productJoin.get("onSale"), true)); //指定商品在售 }; } ``` 以上代码中,我们建立了user表、order表和product表之间的Join关系,并指定了查询条件,即查询某个用户已经完成的订单,并且订单中包含在售商品。注意,我们还使用了query.distinct(true)方法对结果去重。 综上所述,JPA Specification在多表查询时同样适用。我们只需要使用Join方法建立表之间的关联,然后通过where条件指定查询条件即可。如果需要进行多表嵌套查询,则需要在查询条件中同时指定多张表的信息。 ### 回答3: JPA是Java Persistence API的缩写,是Java EE用于管理数据库相关的Java API。JPA Specification则是JPA的规范,它定义了一种标准的Java编程接口,用于实现ORM(对象关系映射)。 多表查询是数据库中常见的查询操作之一,它通过同时查询多个表来获取更多的数据。在JPA中,多表查询可以通过使用JPA Specification来实现。JPA Specification提供了一种标准的API,用于动态构建查询语句,使查询操作更加灵活和可扩展。 在JPA Specification中,可以通过CriteriaQuery和Predicate来实现多表查询。CriteriaQuery是一个查询对象,表示一个查询操作,并在其中定义查询的根实体和查询的列。Predicate则是一个查询条件,用于过滤查询结果。通过将多个Predicate组合在一起,就可以实现复杂的查询条件。 在进行多表查询时,需要先定义多个实体类,并将它们之间的关系映射到数据库中。通过JPA提供的注解,可以将实体类中的字段映射到数据库中的对应列,并定义实体类之间的关联关系。在查询时,就可以通过这些关联关系来进行多表连接查询。 除了使用CriteriaQuery和Predicate进行多表查询外,JPA还提供了JPQL(Java Persistence Query Language)和Native SQL两种查询方式。JPQL类似于SQL,但使用面向对象的语法来查询实体类,更加灵活和方便。Native SQL则直接使用SQL语句来查询数据库,可以处理更复杂的查询操作,但需要手动处理结果集。 在使用JPA Specification进行多表查询时,需要注意查询性能和代码可维护性。多表查询往往会涉及到大量数据,需要合理地设计查询语句和索引,避免出现性能问题。同时,需要确保代码的可读性和可维护性,避免出现过于复杂的查询语句和逻辑。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是汤圆丫

怎么 给1分?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值