• Specifications动态查询


    有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询。相比JPQL,其优势是类型安全,更加的面向对象。

    import java.util.List;
    
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.domain.Sort;
    import org.springframework.data.jpa.domain.Specification;
    
    /**
     *    JpaSpecificationExecutor中定义的方法
     **/
     public interface JpaSpecificationExecutor<T> {
           //根据条件查询一个对象
         T findOne(Specification<T> spec);    
           //根据条件查询集合
         List<T> findAll(Specification<T> spec);
           //根据条件分页查询
         Page<T> findAll(Specification<T> spec, Pageable pageable);
           //排序查询查询
         List<T> findAll(Specification<T> spec, Sort sort);
           //统计查询
         long count(Specification<T> spec);
    }

    对于JpaSpecificationExecutor,这个接口基本是围绕着Specification接口来定义的。我们可以简单的理解为,Specification构造的就是查询条件。

    Specification接口中只定义了如下一个方法:

    //构造查询条件
        /** 
        *    root    :Root接口,代表查询的根对象,可以通过root获取实体中的属性
        *    query    :代表一个顶层查询对象,用来自定义查询
        *    cb        :用来构建查询,此对象里有很多条件方法
        **/
        public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);

    使用Specifications完成条件查询

    //依赖注入customerDao
        @Autowired
        private CustomerDao customerDao;    
        @Test
        public void testSpecifications() {
              //使用匿名内部类的方式,创建一个Specification的实现类,并实现toPredicate方法
            Specification <Customer> spec = new Specification<Customer>() {
                public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                    //cb:构建查询,添加查询方式   like:模糊匹配
                    //root:从实体Customer对象中按照custName属性进行查询
                    return cb.like(root.get("Name").as(String.class), "上海堡%");
                }
            };
            Customer customer = customerDao.findOne(spec);
            System.out.println(customer);
        }

    基于Specifications的分页查询

     @Test
        public void testPage() {
            //构造查询条件
            Specification<Customer> spec = new Specification<Customer>() {
                public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                    return cb.like(root.get("Name").as(String.class), "上海堡%");
                }
            };
    /**
     * 构造分页参数
     * Pageable : 接口
     * PageRequest实现了Pageable接口,调用构造方法的形式构造
     * 第一个参数:页码(从0开始)
     * 第二个参数:每页查询条数
     */
     Pageable pageable = new PageRequest(0, 5);
            
     /**
     * 分页查询,封装为Spring Data Jpa 内部的page bean
     * 此重载的findAll方法为分页方法需要两个参数
     * 第一个参数:查询条件Specification
     * 第二个参数:分页参数
     */
     Page<Customer> page = customerDao.findAll(spec,pageable);
            
        }

    3 方法对应关系

    方法名称

    Sql对应关系

    equle

    filed = value

    gt(greaterThan )

    filed > value

    lt(lessThan )

    filed < value

    ge(greaterThanOrEqualTo )

    filed >= value

    le( lessThanOrEqualTo)

    filed <= value

    notEqule

    filed != value

    like

    filed like value

    notLike

    filed not like value

  • 相关阅读:
    Memcache 内存分配策略和性能(使用)状态检查
    C# 中字符串转换成日期
    Task及Mvc的异步控制器 使用探索
    MVC项目实践,在三层架构下实现SportsStore-01,EF Code First建模、DAL层等
    从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十三║Vue实战:Vuex 其实很简单
    从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十一║Vue实战:开发环境搭建【详细版】
    vue-router 快速入门
    Vue.js——60分钟快速入门
    五小步让VS Code支持AngularJS智能提示
    AngularJS----服务,表单,模块
  • 原文地址:https://www.cnblogs.com/yangzhixue/p/12349051.html
Copyright © 2020-2023  润新知