Spring Data Commons之Repository

256 阅读2分钟

1、Spring Data 生态图

image.png

2、Repository 接口

Repository 是 Spring Data 进行数据库操作的最顶级的抽象接口,任何接口继承它,就能得到一个Repository.

Commons里面的Repository源码如下所示:

@Indexed
public interface Repository<T(实体类), ID(主键)> {
}

2.1 Repository 继承关系图

image.png

  • JpaRepository<T, ID> :JPA的扩展方法
  • PagingAndSortingRepository<T, ID> :带分页和排序的方法
  • QueryByExampleExecutor :简单的Example查询
  • CrudRepository<T, ID> :简单的CRUD方法
  • Repository<T, ID> :没有暴露任何方法

3、CrudRepository接口

CrudRepository提供的方法如下所示:

image.png

  • count(): long 查询总数返回 long 类型;
  • void delete(T entity) 根据 entity 进行删除;
  • void deleteAll(Iterable<? extends T> entities) 批量删除;
  • void deleteAll() 删除所有;
  • void deleteById(ID id); 根据主键删除,查看源码会发现,其是先查询出来再进行删除;
  • boolean existsById(ID id) 根据主键判断实体是否存在;
  • Iterable findAllById(Iterable ids); 根据主键列表查询实体列表;
  • Iterable findAll(); 查询实体的所有列表;
  • Optional findById(ID id); 根据主键查询实体
  • (S extends T) save(S entity); 保存实体方法,参数和返回结果可以是实体的子类;
  • saveAll(Iterable(S) entities) : 批量保存,原理和 save方法相同

3.1 save() 方法的底层原理

原理

  • 如果传递的参数里面没有ID时,直接执行INSERT操作。
  • 如果传递的参数里面有ID时,直接触发SELECT查询,查看数据库中是否存在该记录,存在则执行Update操作,否则执行Insert操作
@Transactional
public <S extends T> S save(S entity) {
    if (this.entityInformation.isNew(entity)) {
        this.em.persist(entity);
        return entity;
    } else {
        return this.em.merge(entity);
    }
}

4、PaingAndSortingRepository接口

主要用于分页查询和排序查询,在PaingAndSortingRepository源码中有两个方法,如下图所示
image.png

  1. Sort类,即根据排序参数实现不同的排序规则.
    image.png
    在上图中,Sort类的有参构造方式是私有的,所以我们不能直接new Sort(...) ,必须通过静态方法Sort.by(...)来完成实例化,如下图所示
    image.png
    如上图所示,Sort.by(Sort.Order ... orders)方法参数是Sort.Order类型。再看Sort.Order类,如下图所示需要指定**Direction(ASC,DESC)Property(排序字段) ** 企业微信截图_16620861604081.png

  2. Pageable类,即根据分页和排序进行查询,并用Page对返回结果进行封装
    Pageable的默认实现类是PageRequest,如下图所示。PageRequest和Sort类有点像,因为PageRequest的构造方法是保护的,需要通过静态方法PageRequest.of(...)来完成实例化。 image.png

4.1测试代码

// 按照id降序排序
userRepo.findAll(Sort.by(new Sort.Order(Sort.Direction.DESC,"id")))
        .forEach(System.out::println);
// 按照id降序排序,查询第一页的3条数据
userRepo.findAll(PageRequest.of(1,3,Sort.by(new Sort.Order(Sort.Direction.DESC,"id"))))
        .forEach(System.out::println);

5、JpaRepository接口

JpaRepository是对关系型数据库进行的抽象封装,而其他的接口都是Spring Data 为了兼容NoSQL而进行的一些抽象封装。JpaRepository方法如下所示:
image.png

6、Repository的实现类 SimpleJpaRepository

SimpleJpaRepository是Repository接口、CrudRepository接口、PageingAndSorting接口、JpaRepository接口的实现。在源码中SimpleJpaRepository的实现机制是通过Entity-Manager进行实体的操作,而JpaEntityInformation里面存在实体的相关信息和CRUD方法的元数据等。

企业微信截图_1662089243374.png