Spring Data JPA(五)—— SpringDataJpa原理及复杂查询

2020-04-02

一、Spring Data JPA运行原理

image.png

  1. 通过JdkDynamicAopProxy的invoke方法创建了一个动态代理对象
  2. SimpleJpaRepository当中封装了JPA的操作(借助JPA的api完成数据库的CRUD)
  3. 通过Hibernate完成数据库操作(封装了JDBC)

二、复杂查询

2.1 借助接口中的定义好的方法完成查询

/**
 * 查询总数
 */
@Test
public void testCount() {
    long count = customerDao.count();
    System.out.println(count);
}

/**
 * 判断id为4的客户是否存在
 */
@Test
public void testExists() {
    boolean flag = customerDao.existsById(4l);
    System.out.println(flag ? "存在" : "不存在");
}

2.2 JPQL查询方式

需要将JPQL语句配置到接口方法上

特有的查询:需要在dao接口上配置方法
在新添加的方法上,使用注解的形式配置JPQL查询语句
注解:@Query

  1. JPQL基本查询

    dao层接口

    @Query(value = "from Customer where custName = ?1")
    public Customer findJpql(String custName);
    

    测试类

    @Test
    public void testFindJpql(){
        Customer cherishVII = customerDao.findJpql("CherishVII");
        System.out.println(cherishVII);
    }
    
  2. JPQL多占位符查询

    dao层接口

    @Query(value = "from Customer where custIndustry = ?1 and custPhone = ?2 ")
    public Customer findByIndustryAndPhone(String industry,String phone);
    

    ?后数字为索引值(以1开头),参数索引对应即可

    测试类

    @Test
    public void testFindByIndustryAndPhone(){
        Customer customer = customerDao.findByIndustryAndPhone("IT","10010");
        System.out.println(customer);
    }
    
  3. 更新操作

    dao层接口

    @Query(value = "update Customer set custPhone = ?2 where custId = ?1 ")
    @Modifying
    public void updateCustomer(Long custId,String phone);
    

    注意@Modifying,表明是更新操作

    测试类

    @Test
    @Transactional //添加事务
    @Commit //手动提交事务(或者@Rollback(value = false))
    public void testUpdate(){
        customerDao.updateCustomer(5l,"10086");
    }
    

    Spring Data JPA中使用JPQL默认会回滚事务,所以需要手动提交,两种方式均可

2.3 SQL查询

需要将SQL语句配置到接口方法上

特有的查询:需要在dao接口上配置方法
在新添加的方法上,使用注解的形式配置SQL查询语句
注解:@Query

value:JPQL语句|Sql语句

nativeQuery:false(不使用本地查询:JPQL查询)|true(使用本地查询:SQL查询)

  1. 查询全部客户

    dao层接口

    @Query(value = "select * from tab_customer ",nativeQuery = true)
    public List<Customer> findAllBySql();
    

    测试类

    @Test
    public void testFindAll(){
        List<Customer> customerList = customerDao.findAllBySql();
        for (Customer customer : customerList) {
            System.out.println(customer);
        }
    }
    
  2. 条件查询

    dao层接口

    @Query(value = "select * from tab_customer where cust_name like ?1 ",nativeQuery = true)
    public List<Customer> findCustomersByCustNameSql(String custName);
    

    测试类

    @Test
    public void testFindByCustNameSql(){
        List<Customer> customerList = customerDao.findCustomersByCustNameSql("test%");
        for (Customer customer : customerList) {
            System.out.println(customer);
        }
    }
    

2.4 方法名称规则查询

是对JPQL查询更加深入的一层封装,只需要按照Spring Data JPA提供的方法名称规则定义方法,不需要再配置JPQL语句,完成查询

  1. 基本查询

    findBy:查询

    对象中的属性名(首字母大写):查询的条件。例:findByCustName

    dao层接口

    public Customer findByCustName(String custName);
    

    测试类

    @Test
    public void testFindByCustName(){
        Customer customer = customerDao.findByCustName("CherishVII");
        System.out.println(customer);
    }
    

    实测findCustomerByCustName也能实现

    跟着idea提示写名称即可

  2. 模糊查询

    findBy + 属性名称 + 查询方式(like|isnull)

    dao层接口

    public List<Customer> findByCustNameLike(String custName);
    

    测试类

    @Test
    public void testFindByCustNameLike(){
        List<Customer> customerList = customerDao.findByCustNameLike("test%");
        for (Customer customer : customerList) {
            System.out.println(customer);
        }
    }
    
  3. 多条件查询

    findBy + 属性名 + 查询方式 + 多条件的连接符 + 属性名 + 查询方式

    dao层接口

    public Customer findByCustNameLikeAndCustPhone(String custName,String custPhone);
    

    测试类

    @Test
    public void testFindByCustNameLikeAndCustPhone(){
        Customer customer = customerDao.findByCustNameLikeAndCustPhone("test%","10086");
        System.out.println(customer);
    }
    

标题:Spring Data JPA(五)—— SpringDataJpa原理及复杂查询
作者:CherishVII
地址:https://cherishvii.com/articles/2020/04/02/1585823600121.html

评论
发表评论