| 来自 Catalin Tudose的《使用Spring Data和Hibernate的Java持久性》。 本文深入探讨了使用Spring Data JPA来访问数据库。 |
在manning.com结账时,在折扣框中输入fcctudose2,可享受35%的*Java Persistence with Spring Data and Hibernate* 。
这篇文章假设了对Spring Data主要模块的了解。
我们在这里将重点讨论Spring Data JPA,因为它是用来与数据库交互的。Spring Data JPA在很大程度上被用作从Java程序访问数据库的替代品。它在JPA提供者(例如Hibernate)之上提供了一个新的抽象层,控制了配置和事务管理。让我们在这里深入分析一下它的能力。我们仍然可以使用JPA和Hibernate来定义和管理我们的实体,但我们将提供Spring Data JPA作为与它们交互的替代方案。
用Spring Data JPA定义查询方法
让我们想象一下,我们有一个名为CaveatEmptor的拍卖系统,我们想要添加功能。我们将通过添加字段email,level, 和active 来扩展User 类。一个用户可以有不同的级别,这将允许他或她执行特定的行动(例如,出价超过某个金额)。一个用户可能是活跃的,也可能是退役的(即以前在CaveatEmptor拍卖系统中活跃)。这是CaveatEmptor应用程序需要保留的关于用户的重要信息。所演示的源代码可以在springdatajpa2 文件夹中找到。
清单1 修改后的用户类
我们将开始向UserRepository 接口添加新的方法,并在新创建的测试中使用它们。
UserRepository 接口将扩展JpaRepository ,它扩展了PagingAndSortingRepository ,而后者又扩展了CrudRepository 。
CrudRepository PagingAndSortingRepository 提供了方便的方法来对记录进行排序和分页(将在本章后面讨论)。 提供了JPA相关的方法,如刷新持久化上下文和批量删除记录。此外, 覆盖了 中的一些方法,如 、 或 ,以返回 而不是 。JpaRepository JpaRepository CrudRepository, findAll findAllById, saveAll List Iterable
我们还将在UserRepository 接口中添加一系列的查询方法,这些方法看起来像这样。
清单 2 带有新方法的 UserRepository 接口
查询方法的目的是为了从数据库中获取信息。Spring Data JPA提供了一个查询生成器机制,它将根据存储库方法的名称来创建它们的行为。我们将在后面分析修改查询的问题,现在我们深入到查询的目的是为了寻找信息。这个查询机制从方法的名称中去除前缀和后缀,如find...By,get...By,query...By,read...By,count...By ,并解析剩下的部分。
你可以将包含表达式的方法声明为Distinct ,以设置一个不同的子句,将运算符声明为LessThan,GreaterThan,Between, 和Like ,或者用And 或Or 的复合条件。你可以在引用属性的查询方法名称中用OrderBy 子句应用静态排序,并提供一个排序方向(Asc 或Desc )。你可以对支持这种子句的属性使用IgnoreCase 。对于删除行,你必须在方法的名称中用delete 替换find 。另外,Spring Data JPA会查看方法的返回类型。如果你想找到一个User ,并在一个Optional 容器中返回它,那么方法的返回类型将是Optional<User> 。可能的返回类型的完整列表,以及详细的解释,可以在docs.spring.io/spring-data…
方法的名称需要遵循规则来确定结果查询。 如果方法的命名是错误的(例如,实体属性在查询方法中不匹配),在应用上下文加载时,你会得到一个错误。
表1描述了Spring Data JPA支持的关键词以及每个方法名称在JPGL中的转置情况。
表1 Spring Data JPA和生成的JPGL中的关键词用法
关键字 | 例子 | 生成的JPGL |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
作为未来所有测试的基类,我们将编写SpringDataJpaApplicationTests 抽象类。
清单3 SpringDataJpaApplicationTests抽象类
#A 由Spring Boot添加到最初创建的类中的@SpringBootTest注解将告诉Spring Boot搜索主配置类(例如,@SpringBootApplication注解类)并创建测试中使用的ApplicationContext。重要的是要理解,Spring Boot为包含main方法的类添加的@SpringBootApplication注解将启用Spring Boot自动配置机制,并将启用对应用程序所在包的扫描,以及允许在上下文中注册额外的bean。
#B 使用@TestInstance(TestInstance.Lifecycle.PER_CLASS)注解,我们要求JUnit 5创建一个测试类的单一实例,并在所有测试方法中重复使用它。这将允许我们使@BeforeAll和@AfterAll注解的方法成为非静态的,并在其中直接使用自动连接的UserRepository实例字段。
#C 我们自动连接一个 UserRepository 实例。这种自动连接是由于@SpringBootApplication注解而实现的,该注解可以扫描应用程序所在的包,并在上下文中注册bean。
#D 在执行来自扩展SpringDataJpaApplicationTests的类的所有测试之前,@BeforeAll注解的方法将被执行一次。这个方法不会是静态的。
#E @TestInstance(TestInstance.Lifecycle.PER_CLASS)注解将强制创建一个测试类的单一实例。它将把由generateUsers方法创建的用户列表保存到数据库中。
#F @AfterAll注解的方法将被执行一次,在执行了所有来自扩展SpringDataJpaApplicationTests的类的测试之后。这个方法将不会是静态的。@TestInstance(TestInstance.Lifecycle.PER_CLASS)注解强制创建一个测试类的单一实例。
接下来的测试将扩展这个类并使用已经填充的数据库。为了测试现在属于UserRepository 的方法,我们将创建FindUsersUsingQueriesTest 类,并遵循编写测试的相同配方:调用资源库方法并验证其结果。
清单4 FindUsersUsingQueriesTest类
限制查询结果、排序和分页
first 和top 关键字(等同于使用)可以限制查询方法的结果。top 和first 关键字后面可以有一个可选的数字值,表示要返回的最大结果大小。如果缺少这个数值,结果大小将是1。
Pageable 是一个用于分页信息的接口。在实践中,我们使用实现它的 类。这个可以指定页码、页面大小和排序标准。PageRequest
我们将为UserRepository 接口添加以下方法。
清单5 在UserRepository接口中限制查询结果、排序和分页
我们将编写以下测试来验证这些新添加的方法如何工作。
清单 6 测试限制查询结果、排序和分页
#A 第一个测试将按照用户名的升序找到第一个用户,按照注册日期的降序找到第一个用户。
#B 找到所有的用户,把它们分成几页,并返回大小为3的第1页(页码从0开始)。
#C 找到前2个2级用户,按注册日期排序。
#D 第二个测试将在用户类上定义一个排序标准。Sort.TypedSort扩展了Sort,可以使用方法句柄来定义属性来进行排序。
#E 我们找到第3级的用户并按注册日期排序,降序排列。
#F 第三个测试将找到按注册日期排序的活跃用户,将其分成若干页,并返回大小为4的第1页(页面编号从0开始)。
如果你想了解更多关于这本书的信息,请在Manning的liveBook平台上查看。
The postUsing Spring Data JPAappeared first onManning.
