zoukankan      html  css  js  c++  java
  • Spring Data JPA:解析CriteriaBuilder

    源码

    在Spring Data JPA相关的文章[地址]中提到了有哪几种方式可以构建Specification的实例,该处需要借助CriteriaBuilder,回顾一下Specification中toPredicate方法的定义,代码如下:

        /**
         * Creates a WHERE clause for a query of the referenced entity in form of a {@link Predicate} for the given
         * {@link Root} and {@link CriteriaQuery}.
         *
         * @param root must not be {@literal null}.
         * @param query must not be {@literal null}.
         * @param criteriaBuilder must not be {@literal null}.
         * @return a {@link Predicate}, may be {@literal null}.
         */
        @Nullable
        Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder);

    解读:

    CriteriaBuilder用于根据特定条件限制查询结果,请参见本文后面的示例。

    CriteriaBuilder接口定义在包路径javax.persistence.criteria下,代码如下:

    /**
     * Used to construct criteria queries, compound selections, 
     * expressions, predicates, orderings.
     *
     * <p> Note that <code>Predicate</code> is used instead of <code>Expression&#060;Boolean&#062;</code> 
     * in this API in order to work around the fact that Java 
     * generics are not compatible with varags.
     *
     * @since 2.0
     */
    public interface CriteriaBuilder {

    类图

    方法定义

    CriteriaBuilder中的一些方法如下图所示:

    解读:

    (1)CriteriaBuilder中的方法分为几个类别,譬如:ordering、aggregate functions、subqueries、equality、comparisons等等。

    (2)CriteriaBuilder中的方法的返回值主要有CriteriaQuery、Expression、Predicate等几种类型。

    示例

    观察CriteriaBuilder中and方法与or方法的定义,如下:

        /**
         * Create a conjunction of the given boolean expressions.
         * @param x  boolean expression
         * @param y  boolean expression
         * @return and predicate
         */
        Predicate and(Expression<Boolean> x, Expression<Boolean> y);
        
        /**
         * Create a conjunction of the given restriction predicates.
         * A conjunction of zero predicates is true.
         * @param restrictions  zero or more restriction predicates
         * @return and predicate
         */
        Predicate and(Predicate... restrictions);
    
        /**
         * Create a disjunction of the given boolean expressions.
         * @param x  boolean expression
         * @param y  boolean expression
         * @return or predicate
         */
        Predicate or(Expression<Boolean> x, Expression<Boolean> y);
    
        /**
         * Create a disjunction of the given restriction predicates.
         * A disjunction of zero predicates is false.
         * @param restrictions  zero or more restriction predicates
         * @return or predicate
         */
        Predicate or(Predicate... restrictions);

    解读:

    上述and方法与or方法用于组合多个查询条件。

    其中Predicate and(Predicate... restrictions);方法接受不定数参数Predicate... restrictions,故可以传入多个Predicate参数,最佳实践是传入一个数组;其意义是用and连接词将多个条件连接起来。

    具体案例——添加多个查询条件

      private Specification createSpecification(Integer specialId, String specialEmail) {
        Specification<User> specification = new Specification<>() {
          @Override
          public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            Path id = root.get("id");
            Predicate predicateId = cb.gt(id, specialId);
    
            Path email = root.get("email");
            Predicate predicateEmail = cb.equal(email, specialEmail);
            
            return cb.and(predicateId, predicateEmail);
          }
        };
    
        return specification;
      }

    解读:

    上述着色处代码以and方法将两个条件组合在一起

    扩展阅读

    JPA Criteria Queries[地址]


    Predicate与Expression

    从前面的分析可知,CriteriaBuilder中的很多方法接受Expression或者Predicate类型的参数,并返回Expression或者Predicate类型的结果,譬如上面提到的and方法,所以本小节来探寻一下Expression与Predicate之间的关系。

    Expression与Predicate之间的关系如下图所示:

    解读:

    Predicate接口继承了Expression接口,所以CriteriaBuilder中接受Expression类型参数的方法(譬如:and方法等)可以接受Predicate类型的参数,正如前面示例所展示的那样。

    Note:

    Path接口也继承了Expression接口,所以CriteriaBuilder中接受Expression类型参数的方法(譬如:lt方法)可以接受Path类型实例:

        Specification<User> specification = new Specification<>() {
          @Override
          public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            Path<Integer> path = root.get("id");
            return cb.lt(path, id);
          }
        };

    解读:

    上述示例在构造了Path类型的变量后调用了lt方法,该方法的定义如下:

        /**
         * Create a predicate for testing whether the first argument is 
         * less than the second.
         * @param x  expression
         * @param y  value
         * @return less-than predicate
         */
        Predicate lt(Expression<? extends Number> x, Number y);
  • 相关阅读:
    EF性能之关联加载
    【迁移】—Entity Framework实例详解
    GRIDVIEW多行多列合并单元格(合并列)
    使用Word2013发布随笔到博客园
    课堂资料下载-有问题加群-为杜绝有广告泛滥.固加群收费.
    strstr ShellCode实现
    X86保护模式入门简介
    WDK7600编译器环境配置
    内核驱动驱动对象 Driver_OBJECT
    基本的三角函数总结
  • 原文地址:https://www.cnblogs.com/studyLog-share/p/15190011.html
Copyright © 2011-2022 走看看