Spring Boot建立在 Spring 之上,包含了 Spring 的所有特性。并且由于其快速的生产就绪环境使开发人员能够直接专注于逻辑而不是为配置和设置而苦苦挣扎,如今它正成为开发人员的最爱。Spring Boot 是一个基于微服务的框架,在其中制作可用于生产的应用程序只需要很少的时间。
CRUD 存储库
Spring Boot 中有一个名为 CrudRepository 的接口,其中包含用于 CRUD 操作的方法。它在存储库上提供通用的 Crud 操作。它在包org.springframework.data.repository中定义,它扩展了 Spring Data Repository 接口。如果有人想在 Spring Boot 应用程序中使用 CrudRepository,他/她必须创建一个接口并扩展 CrudRepository 接口。
句法:
public interface CrudRepository<T, ID> extends Repository<T, ID>
在哪里:
- T:存储库管理的域类型(通常是实体/模型类名)
- ID:存储库管理的实体的 ID 类型(通常是在 Entity/Model 类中创建的 @Id 的包装类)
例子:
public interface DepartmentRepository extends CrudRepository<Department, Long> {}
JpaRepository
JpaRepository 是 Repository 的JPA(Java Persistence API)特定扩展。它包含CrudRepository和PagingAndSortingRepository的完整 API 。因此它包含用于基本 CRUD 操作的 API 以及用于分页和排序的 API。
句法:
public interface JpaRepository<T,ID> extends PagingAndSortingRepository<T,ID>, QueryByExampleExecutor<T>
在哪里:
- T:存储库管理的域类型(通常是实体/模型类名)
- ID:存储库管理的实体的 ID 类型(通常是在 Entity/Model 类中创建的 @Id 的包装类)
例子:
public interface DepartmentRepository extends JpaRepository<Department, Long> {}
Spring 数据存储库接口
在下图中的 Repository、CrudRepository 和 PagingAndSortingRepository 属于 Spring Data Commons 而 JpaRepository 属于 Spring Data JPA。
差异表
Crud存储库 | JpaRepository |
它是一个基本接口并扩展了存储库接口。 | 它扩展了扩展 CrudRepository 的 PagingAndSortingRepository。 |
它包含用于 CRUD 操作的方法。例如 save()、saveAll()、findById()、findAll() 等。 | 它包含 CrudRepository 和 PagingAndSortingRepository 的完整 API。例如,它包含 flush()、saveAndFlush()、saveAllAndFlush()、deleteInBatch() 等以及 CrudRepository 中可用的方法。 |
它没有提供实现分页和排序的方法 | 它提供了所有对实现分页有用的方法。 |
它用作标记界面。 | 它扩展了 CrudRepository 和 PagingAndSortingRepository。 |
要执行 CRUD 操作,请定义扩展 CrudRepository 的存储库。 | 要执行 CRUD 以及批处理操作,请定义存储库扩展 JpaRepository。 |
句法: 公共接口 CrudRepository<T, ID> 扩展 Repository<T, ID> | 句法: 公共接口 JpaRepository<T,ID> 扩展 PagingAndSortingRepository<T,ID>, QueryByExampleExecutor<T> |
Spring Data JPA是一个强大的工具,用于构建使用 JPA(Java Persistence API)作为数据访问层的 Spring 驱动的应用程序。它在现有 JPA 提供程序之上提供了一个额外的抽象层,使应用程序能够通过简单且一致的 API 与不同的数据访问技术进行通信。
Spring Data JPA 的真正优势在于存储库抽象。它抽象了数据存储特定的实现细节,并允许我们在更高的抽象级别上编写业务逻辑代码。我们只需要学习如何使用 Spring Data repository 接口,而不用担心这些接口的实现。Spring Data 为这些存储库接口提供了开箱即用的实现。
在本文中,您将详细了解不同类型的 Spring Data 存储库接口及其特性。在使用 Spring Data JPA 时,您应该了解三个重要的存储库接口:
-
CrudRepository
— 针对特定类型的存储库的通用 CRUD(创建、读取、更新和删除)操作的接口。 -
PagingAndSortingRepository
— 扩展CrudRepository
以提供额外的方法来使用分页和排序抽象检索实体。 -
JpaRepository
— to 的扩展PagingAndSortingRepository
提供了 JPA 相关的方法,例如刷新持久化上下文和批量删除记录。由于继承,它包含前两个存储库接口的所有方法。
所有这些存储库接口都直接或间接地扩展了顶级 Spring DataRepository
接口。它充当中央存储库制造商接口,并捕获要管理的域类型以及域类型的 id 类型。
让我们看一下CrudRepository
、PagingAndSortingRepository
和JpaRepository
存储库以及它们定义的方法。
CrudRepository
界面
顾名思义,该CrudRepository
接口定义了一个存储库,该存储库提供用于创建、读取、更新和删除实体的标准 CRUD 方法。
下面是CrudRepository
接口定义的样子:
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
<S extends T> S save(S entity);
<S extends T> Iterable<S> saveAll(Iterable<S> entities);
Optional<T> findById(ID id);
boolean existsById(ID id);
Iterable<T> findAll();
Iterable<T> findAllById(Iterable<ID> ids);
long count();
void deleteById(ID id);
void delete(T entity);
void deleteAll(Iterable<? extends T> entities);
void deleteAll();
}
现在让我们一一看看上述所有方法:
-
save()
— 保存给定的实体。将返回持久化的实体,并初始化所有自动生成的默认字段。 -
saveAll()
— 保存一个可迭代的实体。它以可迭代的形式返回所有持久化的实体。 -
findById()
— 根据主键值检索单个实体。 -
existsById()
— 返回具有给定 ID 的实体是否存在。 -
findAll()
— 返回数据库中该类型的所有可用实体的可迭代对象。 -
findAllById()
— 返回与给定 ID 匹配的所有实体的可迭代对象。 -
count()
— 返回可用实体的总数。 -
deleteById()
— 删除具有给定 ID 的实体。 -
delete()
— 查找并删除与给定实体匹配的实体。 -
deleteAll()
— 删除在给定迭代中匹配的所有实体。如果没有提供可迭代对象,它将删除所有实体。
正如您在上面看到的,该CrudRepository
接口提供了用于管理实体的典型 CRUD 功能。
要在您的应用程序中使用此存储库接口,只需创建一个扩展 的新 Java 接口,CrudRepository
如下所示:
public interface MovieRepository extends CrudRepository<Movie, Long> { }
查看使用 Spring Data JPA 和 MySQL 访问数据教程,了解有关使用
CrudRepository
数据操作的更多信息。
PagingAndSortingRepository
界面
该PagingAndSortingRepository
接口是它的扩展,CrudRepository
它提供了两种附加方法,用于对查询结果应用动态分页和排序。
下面是PagingAndSortingRepository
定义的样子:
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
}
-
findAll(Sort sort)
— 返回按给定Sort
对象排序的所有实体。 -
findAll(Pageable pageable)
— 返回与给定对象Page
提供的分页条件匹配的实体。Pageable
让我们创建一个扩展接口的新存储库PagingAndSortingRepository
接口:
public interface SongRepository extends PagingAndSortingRepository<Song, Long> { }
要将动态排序应用于查询结果,您需要创建一个实例Sort
并将其作为参数传递给findAll()
:
Sort sort = Sort.by("title").descending();
List<Song> songs = songRepository.findAll(sort);
如果要对查询结果进行分页,需要创建一个Pageable
接口实例,如下:
Pageable pageable = PageRequest.of(0, 10);
Page<Song> songs = songRepository.findAll(pageable);
您甚至可以使用Pageable
界面将排序与分页结合起来:
Pageable pageable = PageRequest.of(0, 10, Sort.by("title").descending());
Page<Song> songs = songRepository.findAll(pageable);
JpaRepository
界面
最后,让我们看一下JpaRepository
接口定义:
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
List<T> findAll();
List<T> findAll(Sort sort);
List<T> findAllById(Iterable<ID> ids);
<S extends T> List<S> saveAll(Iterable<S> entities);
void flush();
<S extends T> S saveAndFlush(S entity);
void deleteInBatch(Iterable<T> entities);
void deleteAllInBatch();
T getOne(ID id);
@Override
<S extends T> List<S> findAll(Example<S> example);
@Override
<S extends T> List<S> findAll(Example<S> example, Sort sort);
}
上面的大部分JpaRepository
方法都是继承自PagingAndSortingRepository
和QueryByExampleExecutor
接口。让我们看看其他方法:
-
flush()
— 刷新对数据库的所有挂起更改。 -
saveAndFlush()
— 保存给定的实体并立即将更改刷新到数据库。 -
deleteInBatch()
— 使用单个查询批量删除给定实体。 -
deleteAllInBatch()
— 删除批量调用中的所有实体。 -
getOne()
— 根据给定的主键值返回单个实体。
由于JpaRepository
存储库 extends PagingAndSortingRepository
,它继承了PagingAndSortingRepository
和CrudRepository
接口的所有方法。
使用 Spring 数据存储库
要使用任何 Spring Data 存储库,您只需创建一个新的存储库接口并扩展上述任何存储库。
以下示例CatRepository
通过扩展 Spring Data JPA 定义了一个接口,JpaRepository
还声明了查询方法以Cat
从数据库中检索实体:
public interface CatRepository extends JpaRepository<Cat, Long> {
Cat findByName(String name);
List<Cat> findByColor(String color);
Page<Cat> findByAgeLessThan(int age, Pageable pageable)
}