Spring Data Jpa底层原理剖析、JPQL查询、方法命名规则查询

本文深入探讨了Spring Data Jpa的底层原理,包括动态代理和反射的应用。详细分析了接口定义方法查询、JPQL查询、SQL查询以及方法命名规则查询的使用方式和技巧,如findOne、getOne、分页排序、统计和对象存在性判断。此外,还介绍了@Query注解在JPQL查询和更新操作中的应用。
摘要由CSDN通过智能技术生成

1.1 Spring Data Jpa底层原理解析

  •  目标:知道它是怎么运行的?底层到底封装的是谁?、
  • 明确一点:我们所使用的所有框架,底层大多数都使用了动态代理技术、反射技术来封装实现

 分析步骤:

  1. 我们只写了接口,但是没有写实现类,这个实现类就是Spring在运行的时候,注入的代理对象
  2. Spring怎么知道生成的那个dao的实现类?因为在配置文件中指定了dao接口所在的包
  3. 生成的是什么对象?代理对象:通过jdk生成的动态代理对象
    Proxy.newProxyInstance(类加载器,实现的接口列表,InvocationHandler)
    JdkDynamicAopProxy: 这个是个对象,实现了InvocationHandler接口,所以这个类有invoke方法
  4. 在JdkDynamicAopProxy的invoke方法中有个target对象,这个对象就是真正干活的对象
  5. 真正干活的对象:SimpleJpaRepository
  6. SimpleJpaRepository实现了我们dao接口继承的那两个接口,所以这个类中肯定有接口的所有方法
  7. 我们看到findOne方法中调用了em.find方法,这个em到底是谁?

 1.2 Spring Data Jpa常用接口分析


2.1 查询方式一:接口定义方法查询:查询一个的两种方法

  • 目标:查询一个对象的两种方法
  • findOne(主键值):底层调用的是em.find()             :立即加载
  • getOne(主键值) : 底层调用的是em.getReference() : 延迟加载
package com.sunny.SpringDataJpaTest;

import com.sunny.dao.CustomerDao;
import com.sunny.domain.Customer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringJUnit4ClassRunner.class)//替换运行器
@ContextConfiguration("classpath:/applicationContext.xml")//指定核心配置文件
public class Interface_Method_Query {

    @Autowired
    private CustomerDao customerDao;

    /**
     * 查询一个对象
     *      findOne();    em.finc(Class,id)         立即加载
     *      getOne();     em.getReference(Class,id) 延迟加载
     *
     *  细节:
     *        在使用延迟加载的时候,需要用到事务,如果没有事务,会报错
     *        could not initialize proxy - no Session 异常
     *
     *        为了解决这个异常:我们手动在测试方法中加入@Transactional注解
     *        在以后真正的项目中,我们配置了声明式事务,这个注解就不用写了
     *
     */
    @Test
    @Transactional
    public void test01(){
        //Customer c = customerDao.findOne(2L);
        Customer c = customerDao.getOne(2L);
        System.out.println(c);
    }
}

2.2 查询方式一:接口定义方法查询:查询所有的分页与排序查询

目标:查询所有的分页与排序查询

import com.sunny.dao.CustomerDao;
import com.sunny.domain.Customer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;


@RunWith(SpringJUnit4ClassRunner.class)//替换运行器
@ContextConfiguration("classpath:/applicationContext.xml")//指定核心配置文件
public class Interface_Method_Query {

    @Autowired
    private CustomerDao customerDao;

/**
     * 查询所有:
     *      1)排序
     *      2)分页
     */
    @Test
    public void test2(){
        //排序对象
        /**
         * 第一个参数: 排序规则: asc | desc
         * 第二个参数: 排序的实体类的属性名称
         */
        Sort s = new Sort(Sort.Direction.DESC,"custId");

        //分页
        /**
         * 第一个参数:当前页:  从0开始,0代表第一页;1代表第二页;2代表第三页........
         * 第二个参数:页大小
         * 第三个参数:排序对象,可以为空
         */
        Pageable p = new PageRequest(0,2,s);

        //查询
        Page<Customer> page = c	ustomerDao.findAll(p);

        System.out.println("总记录数:"+page.getTotalElements());
        System.out.println("总页数:"+page.getTotalPages());
        Syst
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hyhcloud

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值