P1M3_Spring Data JPA 框架

145 阅读2分钟

文章内容输出来源:拉钩教育Java高薪训练营

Spring Data JPA 框架

Dao层框架,简化数据库开发。很多场景下连sql都不需要开发

Spring Data JPA概述

spring.io/projects/sp…

Spring 基于JPA 规范的基础上封装的⼀套 JPA 应⽤框架,可使开发者⽤极简的代码即可实现对数据库的访问和操作。

Spring Data JPA, JPA规范和Hibernate之间的关系

  • JPA规范(Java Persistence API),制定了一些列的接口和抽象类。
  • 成熟的 ORM 框架,Hiberanate 实现了 JPA 规范,所以可以称 Hiberanate 为 JPA 的⼀种实现⽅式。
  • Spring Data JPA 是 Spring 提供的⼀套对 JPA 操作更加⾼级的封装,是在 JPA 规范下的专⻔⽤来进⾏数据持久化的解决⽅案。

Spring Data JPA应用

开发步骤

  • 创建⼯程导⼊坐标(Java框架于我们⽽⾔就是⼀堆jar)
  • 配置 Spring 的配置⽂件(配置指定框架执⾏的细节)
  • 编写实体类 Resume,使⽤ JPA 注解配置映射关系
  • 编写⼀个符合 Spring Data JPA 的 Dao 层接⼝(ResumeDao接⼝)
  • 操作 ResumeDao 接⼝对象完成 Dao 层开发

示例项目

  • 常规CRUD,调用继承接口中的方法

  • 引入jpql

  • 引入sql

  • 方法命名规则查询:在接口中自定义方法,而且不用写jpql或sql

  • 动态查询,service传入dao的条件不确定,把条件封装成对象传入,即Specification

    // 根据条件查询单个对象
    Optional<T> findOne(@Nullable Specification<T> var1);
    // 根据条件查询所有
    List<T> findAll(@Nullable Specification<T> var1);
    // 根据条件查询并进⾏分⻚
    Page<T> findAll(@Nullable Specification<T> var1, Pageable var2);
    // 根据条件查询并进⾏排序
    List<T> findAll(@Nullable Specification<T> var1, Sort var2);
    // 根据条件统计
    long count(@Nullable Specification<T> var1);
    
    @Test
    public void testSpecification() {
    
        // 动态条件封装
        // 匿名内部类
        Specification<Resume> specification = (Specification<Resume>) (root, query, criteriaBuilder) -> {
            Path<Object> name = root.get("name");
            Path<Object> address = root.get("address");
            Predicate predicate1 = criteriaBuilder.equal(name, "张三");
            Predicate predicate2 = criteriaBuilder.like(address.as(String.class), "北%");
            return criteriaBuilder.and(predicate1, predicate2);
        };
    
        Optional<Resume> one = resumeDao.findOne(specification);
        Resume resume = one.get();
        System.out.println(resume);
    }
    
  • 排序

    @Test
    public void testSort() {
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        List<Resume> all = resumeDao.findAll(sort);
        for (Resume resume : all) {
            System.out.println(resume);
        }
    }
    
  • 分页

    @Test
    public void testPageable() {
        PageRequest pageable = PageRequest.of(0, 2);
        Page<Resume> all = resumeDao.findAll(pageable);
        for (Resume resume : all) {
            System.out.println(resume);
        }
    }
    

Spring Data JPA执行过程源码分析

  • resumeDao是⼀个SimpleJapRepository类型的代理对象,如何产生?

image-20201025122853650

  • 通过refresh()核心方法查看代理对象的产生过程
org.springframework.context.support.AbstractApplicationContext#refresh
|
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
|
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

image-20201025123809036

  • 为什么是JpaRepositoryFactoryBean?如何指定的?

image-20201025130643873

  • JpaRespositoryFactoryBean是⼀个什么样的类?

    image-20201025140724024

    image-20201025141355162

  • SimpleJpaRepository

    image-20201025142234455