Spring 全家桶之 Spring Data JPA(三)

简介: Spring 全家桶之 Spring Data JPA(三)

如何在Spring Data JPA中实现动态查询

Specifications动态查询方法

T findOne(Specification<T> spec); //查询单个
List<T> findAll(Specification<T> spec); //查询列表
List<T> findAll(Specification<T> spec, Sort sort); //排序查询
Page<T> findAll(Specification<T> spec, Pageable pageable); //分页查询
long count(Specification<T> spec); //统计查询

查询条件-Specification

自定义Specification实现类,实现

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

构造查询条件,参数如下bf1d1166f3734924996cec7c5063b871_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

  • Root:查询的对象,查询条件/属性都可以从root对象中获取
  • CriteriaQuery:上层查询对象,定义查询方式,一般不用
  • CriteriaQueryBuilder:查询对象的构造器,封装了较多的查询条件

动态查询实现

1.新建Maven项目,加入Maven依赖 2.新建entity包,增加实体类Customer 3.新建dao包,增加CustomerDao 4.在test包中新建dao包,增加CustomerDao

findOne(Specification spec)

直接在CustomerDaoTest中书写测试方法

@Test
public void testFindOne(){
    // 匿名内部类
    Specification<Customer> specification = (Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
        // 构造查询条件,实现toPredicate方法
        //1.获取比较的属性
        Path<Object> custName = root.get("custName");
        //2.构造查询条件,equal为精准匹配
        Predicate thor_odin = cb.equal(custName, "Thor Odin");
        return thor_odin;
    };
    Customer one = customerDao.findOne(specification);
    System.out.println(one);
}

使用了lambda表达式实现Specification匿名内部类,测试结果如下

image.png

多个条件查询,使用and或者or连接多个查询条件

@Test
public void testFindOneByMultiCondition(){
    Specification<Customer> specification = (Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
        // 构造查询条件,实现toPredicate方法
        //1.获取比较的属性
        Path<Object> custName = root.get("custName");
        Path<Object> custIndustry = root.get("custIndustry");
        //2.构造查询条件,equal为精准匹配
        Predicate thor_odin = cb.equal(custName,"Thor Odin");
        Predicate asgard = cb.equal(custIndustry, "God of Thunder");
        // 组合查询条件,以与的形式组合查询条件,也可以使用or
        Predicate mutil = cb.and(thor_odin, asgard);
        return mutil;
    };
    Customer one = customerDao.findOne(specification);
    System.out.println(one);
}

image.png

findAll(Specification spec)实现模糊查询

/**
 * equal方法可以直接使用path属性及属性值的方式得到Predicate对象
 * gt,lt,ge,le,like需要使用path属性.as(属性类型.class)及属性vlaue来得到Predicate对象
 */
@Test
public void testFindAllByLike(){
    Specification<Customer> specification = (Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
        // 构造查询条件,实现toPredicate方法
        //1.获取比较的属性
        Path<Object> custSource = root.get("custSource");
        Predicate like = cb.like(custSource.as(String.class), "FB%");
        return like;
    };
    List<Customer> all = customerDao.findAll(specification);
    for (Customer customer : all) {
        System.out.println(customer);
    }
}

image.png

List findAll(Specification spec, Sort sort); 排序查询

@Test
    public void testFindAllByLikeAsc(){
        Specification<Customer> specification = (Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            // 构造查询条件,实现toPredicate方法
            //1.获取比较的属性
            Path<Object> custSource = root.get("custSource");
            Predicate like = cb.like(custSource.as(String.class), "FB%");
            return like;
        };
        // 排序规则,倒叙排列
        Sort sort = new Sort(Sort.Direction.DESC,"custId");
        List<Customer> all = customerDao.findAll(specification,sort);
        for (Customer customer : all) {
            System.out.println(customer);
        }
    }
}

使用Sort构造排序规则,需要两个参数,排序规则和排序字段,输出结果如下

image.png

Page findAll(Specification spec, Pageable pageable)分页查询

先通过save()方法往表中添加数据

@Test
public void testInsert(){
    for (int i = 1; i <= 30; i++) {
        Customer customer = new Customer();
        customer.setCustName("Spider Army No " + i);
        customer.setCustIndustry("Queen");
        customer.setCustLevel("LV 1");
        customerDao.save(customer);
    }
}

新增分页测试代码

@Test
public void testPaging(){
    Specification spec = null;
    // 当前查询页数和每页查询数量
    Pageable pageable = new PageRequest(0,5);
    Page<Customer> all = customerDao.findAll(null,pageable);
    //获取总页数
    System.out.println(all.getTotalPages());
    // 获取数据总量
    System.out.println(all.getTotalElements());
    // 获取当前页数据集合
    List<Customer> content = all.getContent();
    // 遍历集合,得到当前页的所有Customer数据
    for (Customer customer : content) {
        System.out.println(customer);
    }
}

执行分页查询测试成功查出首页数据

image.png


相关文章
|
4月前
|
druid Java 数据库连接
SpringBoot原理分析 | Spring Data整合:JDBC、Druid、Mybatis
SpringBoot原理分析 | Spring Data整合:JDBC、Druid、Mybatis
62 0
|
4月前
|
XML Java 数据库连接
Spring Boot的数据访问之Spring Data JPA以及Hibernate的实战(超详细 附源码)
Spring Boot的数据访问之Spring Data JPA以及Hibernate的实战(超详细 附源码)
46 0
|
4月前
|
Java Spring
Spring Boot利用Spring Data JPA实现排序与分页查询实战(附源码,超详细)
Spring Boot利用Spring Data JPA实现排序与分页查询实战(附源码,超详细)
72 0
|
1月前
|
Java 数据库 Spring
如何使用Spring Data JPA完成审计功能
如何使用Spring Data JPA完成审计功能
|
3月前
|
Java 数据库连接 API
Spring Boot整合Spring Data JPA进行CRUD和模糊查询
Spring Boot整合Spring Data JPA进行CRUD和模糊查询
37 0
|
4月前
|
缓存 NoSQL Java
Spring Data Redis对象缓存序列化问题
在使用 Redis 时,有没有遇到同我一样,对象缓存序列化问题的呢?
67 6
Spring Data Redis对象缓存序列化问题
|
4月前
|
存储 Java 数据库连接
Spring Boot 嵌入式服务器、Hibernate 关系和 Spring Data 全解析
Spring Boot 的嵌入式服务器功能是一项方便而强大的功能,它允许你在应用程序中直接运行 Web 服务器,无需将其部署到单独的独立 Web 服务器中。这使得开发、测试和部署 Web 应用程序变得容易,而且它还是轻量级的、易于启动和停止的,易于配置。
64 0
|
4月前
|
存储 Java 网络架构
Spring Data Elasticsearch基础入门详解
Spring Data Elasticsearch基础入门详解
119 0
|
4月前
|
SQL Java Spring
Spring Data JPA之JpaSpecificationExecutor复杂动态查询实例
Spring Data JPA之JpaSpecificationExecutor复杂动态查询实例
31 0
|
4月前
|
SQL Java 数据库
Spring Data JPA 查询方法那些事
Spring Data 提供了几个接口供继承使用,如 JpaRepository,另外还规定了方法查询中的关键字,即你命名的查询方法需要符合规范。
87 0

热门文章

最新文章