SpringDataJpa动态查询

本文详细介绍了如何在Spring Data JPA中使用Specifications进行动态查询,包括分页查询、多表设计及关联关系的配置,如一对多、多对多的实现。还探讨了一对多操作中的级联删除策略,并讨论了对象导航查询及其延迟加载和立即加载的配置方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 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);

    1. 使用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("custName").as(String.class), "传智播客%");

            }

        };

        Customer customer = customerDao.findOne(spec);

        System.out.println(customer);

    }

    1. 基于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("custName").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);

       

    }

对于Spring Data JPA中的分页查询,是其内部自动实现的封装过程,返回的是一个Spring Data JPA提供的pageBean对象。其中的方法说明如下:

     //获取总页数

    int getTotalPages();

     //获取总记录数  

long getTotalElements();

//获取列表数据

List<T> getContent();

    1. 方法对应关系

方法名称

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

  1. 多表设计

    1. 表之间关系的划分

数据库中多表之间存在着三种关系,如图所示。

从图可以看出,系统设计的三种实体关系分别为:多对多、一对多和一对一关系。注意:一对多关系可以看为两种:  即一对多,多对一。所以说四种更精确。

明确: 我们今天只涉及实际开发中常用的关联关系,一对多和多对多。而一对一的情况,在实际开发中几乎不用。

    1. 在JPA框架中表关系的分析步骤

在实际开发中,我们数据库的表难免会有相互的关联关系,在操作表的时候就有可能会涉及到多张表的操作。而在这种实现了ORM思想的框架中(如JPA),可以让我们通过操作实体类就实现对数据库表的操作。所以今天我们的学习重点是:掌握配置实体之间的关联关系。

第一步:首先确定两张表之间的关系。

         如果关系确定错了,后面做的所有操作就都不可能正确。

第二步:在数据库中实现两张表的关系

第三步:在实体类中描述出两个实体的关系

第四步:配置出实体类和数据库表的关系映射(重点)

  1. JPA中的一对多

    1. 示例分析

 我们采用的示例为客户和联系人。

 客户:指的是一家公司,我们记为A。

 联系人:指的是A公司中的员工。

 在不考虑兼职的情况下,公司和员工的关系即为一对多。

    1. 表关系建立

在一对多关系中,我们习惯把一的一方称之为主表,把多的一方称之为从表。在数据库中建立一对多的关系,需要使用数据库的外键约束。

什么是外键?

指的是从表中有一列,取值参照主表的主键,这一列就是外键。

一对多数据库关系的建立,如下图所示

 

    1. 实体类关系建立以及映射配置

在实体类中,由于客户是少的一方,它应该包含多个联系人,所以实体类要体现出客户中有多个联系人的信息,代码如下:

/**

 * 客户的实体类

 * 明确使用的注解都是JPA规范的

 * 所以导包都要导入javax.persistence包下的

 */

@Entity//表示当前类是一个实体类

@Table(name="cst_customer")//建立当前实体类和表之间的对应关系

public class Customer implements Serializable {

   

    @Id//表明当前私有属性是主键

    @GeneratedValue(strategy=GenerationType.IDENTITY)//指定主键的生成策略

    @Column(name="cust_id")//指定和数据库表中的cust_id列对应

    private Long custId;

    @Column(name=

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值