转载

Spring Data Jpa 基础查询方法原理说明

一、Spring Data Common的Repository

Repository(包括子接口)位于Spring Data Common的lib里面,是Spring Data 里面做数据库操作的最底层的抽象接口,最顶级的父接口,源码中什么方法都没有,仅仅起到一个标示作用。

管理域类以及域类的id类型作为类型参数,此接口主要作为标记接口捕获要使用的类型,并帮助你发现扩展此接口的接口。Spring底层做动态代理的时候发现只要是它的子类或者实现类,都代表储存库操作。

Repository源码如下:

package org.springframework.data.repository;
import org.springframework.stereotype.Indexed;
@Indexed
public interface Repository<T, ID> {
}

有了这个类,我们就能够顺藤摸瓜,找到好多 Spring Data Jpa 提供的基本接口和操作类,及其实现方法。这个接口定义了所有 Repository 操作中的实体和ID两个泛型参数。我们不需要继承任何接口,只要继承这个接口,就可以使用Spring JPA里面提供的很多约定的方法查询和注解查询。

Spring Data Jpa 基础查询方法原理说明
Spring data jpa diagms

二、CrudRepository方法详解

首先继承 Repository 的就是 CrudRepository 了,此类提供了公共的通用 CRUD 方法。

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
    <S extends T> S save(S var1);
    <S extends T> Iterable<S> saveAll(Iterable<S> var1);
    Optional<T> findById(ID var1);
    boolean existsById(ID var1);
    Iterable<T> findAll();
    Iterable<T> findAllById(Iterable<ID> var1);
    long count();
    void deleteById(ID var1);
    void delete(T var1);
    void deleteAll(Iterable<? extends T> var1);
    void deleteAll();
}

2.1、保存实体方法。我们通过刚才的类关系查看其他实现类

SimpleJpaRepository里面的实现方法

public <S extends T> S save(S entity) { 
if (entityInformation.isNew(entity) ) {
em.persist(entity); 
return entity;
} else {
return em.merge(entity);
}

我们发现它是先检查传进去的实体是不是存在,然后判断是新增还是更新;是不是存在两种根据机制,一种是根据主键来判断,另一种是根据Version来判断。如果我们去看JPA控制台打印出来的SQL,最少会有两条,一条是查询,一条是insert或者update。

PS 其他的方法:保存全部、查找、是否存在、删除等方法就不再赘述。

三、PagingAndSortingRepository 方法详解

通过类的关系图,我们可以看到PagingAndSortingRepository继承CrudRepository所有的基本方法,它增加了分页和排序等对查询结果进行限制的基本的、常用的、通用的一些分页方法。

3.1、PagingAndSortingRepository interface 内容

package org.springframework.data.repository; 
import java.io.Serializable; 
import org.springframework.data-domain.Page; 
import org.springframework.data.domain.Pageable; 
import org.springframework.data.domain.Sort;

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID extends Serializable> extends 
CrudRepository<T, ID> {
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);

1、根据排序取所有对象的集合。

2、根据分页和排序进行查询,并用Page对象封装。Pageable对象包含分页和Sort对象。

PagingAndSortingRepository和CrudRepository都是Spring Data Common的标准接口,如果我们采用JPA,那它对应的实现类就是Spring Data JPA的model里面的SimpleJpaRepository。如果是其他NoSQL的实现Mongodb,那它的实现就在Spring Data Mongodb的model里面。

四、JpaRepository方法详解

JpaRepository到这里可以进入分水岭了,上面的那些都是Spring Data为了兼容NoSQL而进行的一些抽象封装,从JpaRepository开始是对关系型数据库进行抽象封装。从类图可以看得出来它继承了PagingAndSortingRepository类,也就继承了其所有方法,并且实现类也是SimpleJpaRepository。从类图上还可以看出JpaRepository继承和拥有了QueryByExampleExecutor的相关方法。

@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>,
 QueryByExampleExecutor<T> {
//无条件查询 获取整个表 相当于 SELECT * FROM table_name;
    List<T> findAll();
    //增加排序
    List<T> findAll(Sort sort);
        //通过一个id序列获取列表
    List<T> findAllById(Iterable<ID> ids);
    //通过id查询
    T getOne(ID id);
    ...
}

通过源码和CrudRepository相比较,它支持Query By Example,批量删除,提高删除效率,手动刷新数据库的更改方法,并将默认实现的查询结果变成了List。

五、Repository的实现类SimpleJpaRepository

SimpleJpaRepository是JPA整个关联数据库的所有Repository的接口实现类。如果想进行扩展,可以继承此类,如QueryDsl的扩展,还有默认的处理机制。如果将此类里面的实现方法看透了,基本上JPA的API就能掌握大部分。同时也是Spring JPA动态代理的实现类,包括我们后面讲的Query Method。

原文  https://cn-blogs.cn/archives/8447.html
正文到此结束
Loading...