Contents

Spring Data JPA简介

1.概述

本教程将重点**介绍将 Spring Data JPA 引入 Spring 项目,**并全面配置持久层。有关使用基于 Java 的配置和项目的基本 Maven pom 设置 Spring 上下文的分步介绍,请参阅本文

2. Spring Data Generated DAO – 不再有 DAO 实现

正如我们在之前的文章中所讨论的,DAO 层 通常由许多可以而且应该被简化的样板代码组成。这种简化的优点有很多:减少了我们需要定义和维护的工件数量、数据访问模式的一致性以及配置的一致性。

Spring Data 将这种简化更进一步,使得完全删除 DAO 实现成为可能。DAO 的接口现在是我们需要明确定义的唯一工件。

为了开始利用 JPA 的 Spring Data 编程模型,DAO 接口需要扩展 JPA 特定的Repository接口JpaRepository。这将使 Spring Data 能够找到这个接口并自动为其创建一个实现。

通过扩展接口,我们获得了标准 DAO 中可用的标准数据访问最相关的 CRUD 方法。

3.自定义访问方法和查询

如前所述,通过实现Repository接口之一,DAO 将已经定义和实现了一些基本的 CRUD 方法(和查询)。 为了定义更具体的访问方法,Spring JPA 支持很多选项:

  • 只需在接口中定义一个新方法
  • 使用*@Query*注释提供实际的JPQL 查询
  • 在 Spring Data 中使用更高级的Specification 和 Querydsl 支持
  • 通过 JPA 命名查询定义自定义查询

第三个选项 Specifications and Querydsl support 与 JPA Criteria 类似,但使用了更灵活方便的 API。这使得整个操作更具可读性和可重用性。当处理大量固定查询时,此 API 的优势将变得更加明显,因为我们可以通过较少数量的可重用块更简洁地表达这些。

最后一个选项的缺点是它要么涉及 XML,要么给域类增加了查询负担。

3.1. 自动自定义查询

当 Spring Data 创建一个新的Repository实现时,它会分析接口定义的所有方法,并尝试从方法名称自动生成查询。虽然这有一些限制,但它是一种非常强大且优雅的方式,可以轻松定义新的自定义访问方法。

让我们看一个例子。如果实体有一个name 字段(以及 Java Bean 标准的getNamesetName方法),**我们将在 DAO 接口中定义findByName方法。**这将自动生成正确的查询:

public interface IFooDAO extends JpaRepository<Foo, Long> {
    Foo findByName(String name);
}

这是一个比较简单的例子。查询创建机制支持更大的关键字集

如果解析器无法将属性与域对象字段匹配,我们将看到以下异常:

java.lang.IllegalArgumentException: No property nam found for type class com.blogdemo.spring.data.persistence.model.Foo

3.2. 手动自定义查询

现在让我们看一下我们将通过*@Query*注释定义的自定义查询:

@Query("SELECT f FROM Foo f WHERE LOWER(f.name) = LOWER(:name)")
Foo retrieveByName(@Param("name") String name);

要对查询的创建进行更细粒度的控制,例如使用命名参数或修改现有查询,参考 是一个很好的起点。

4.交易配置

Spring 管理的 DAO 的实际实现确实是隐藏的,因为我们不直接使用它。但是,它是一个足够简单的实现,SimpleJpaRepository,它使用 annotations 定义事务语义

更明确地说,这在类级别使用只读*@Transactional*注解,然后为非只读方法覆盖该注解。其余的事务语义是默认的,但是可以很容易地通过每个方法手动覆盖这些语义。

4.1. 异常转换很活跃

现在的问题变成了:由于 Spring Data JPA 不依赖于旧的 ORM 模板(JpaTemplateHibernateTemplate),并且自 Spring 5 以来它们已被删除,我们是否仍将 JPA 异常转换为 Spring 的DataAccessException层次结构?

答案是,当然,我们是。通过在 DAO 上使用@Repository*注解仍然可以启用异常转换*。此注解使 Spring bean 后处理器能够通知所有*@Repository* bean 以及在容器中找到的所有PersistenceExceptionTranslator实例,并像以前一样提供异常转换。

让我们通过集成测试来验证异常转换:

@Test(expected = DataIntegrityViolationException.class)
public void givenFooHasNoName_whenInvalidEntityIsCreated_thenDataException() {
    service.create(new Foo());
}

请记住,**异常转换是通过代理完成的。**为了让 Spring 能够围绕 DAO 类创建代理,这些代理不能声明为final

5. Spring Data JPA 存储库配置

要激活 Spring JPA 存储库支持,我们可以使用*@EnableJpaRepositories*注释并指定包含 DAO 接口的包:

@EnableJpaRepositories(basePackages = "com.blogdemo.spring.data.persistence.repository") 
public class PersistenceConfig { 
    ...
}

我们可以对 XML 配置做同样的事情:

<jpa:repositories base-package="com.blogdemo.spring.data.persistence.repository" />

6. Java 或 XML 配置

我们已经在之前的文章中详细讨论了如何在 Spring 中配置 JPA 。Spring Data 还利用了 Spring 对 JPA @PersistenceContext注解的支持。它使用它将EntityManager连接到负责创建实际 DAO 实现JpaRepositoryFactoryBean的 Spring 工厂 bean 。

除了已经讨论过的配置,如果我们使用 XML,我们还需要包含 Spring Data XML Config:

@Configuration
@EnableTransactionManagement
@ImportResource("classpath*:*springDataConfig.xml")
public class PersistenceJPAConfig {
    ...
}

7. Maven依赖

除了 JPA 的 Maven 配置,就像在之前的文章 中一样,我们将添加spring-data-jpa依赖 项:

<dependency>
   <groupId>org.springframework.data</groupId>
   <artifactId>spring-data-jpa</artifactId>
   <version>2.4.0</version>
</dependency>

8. 使用 Spring Boot

我们还可以使用Spring Boot Starter Data JPA 依赖项,它会自动为我们配置DataSource

我们需要确保我们要使用的数据库存在于类路径中。在我们的示例中,我们添加了 H2 内存数据库:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
   <version>2.6.1</version>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.200</version>
</dependency>

结果,只需执行这些依赖项,我们的应用程序就可以启动并运行,我们可以将其用于其他数据库操作。

标准 Spring 应用程序的显式配置现在包含在 Spring Boot 自动配置中。

当然,我们可以通过添加我们自定义的显式配置来修改自动配置。

Spring Boot 提供了一种使用application.properties文件中的属性的简单方法。让我们看一个更改连接 URL 和凭据的示例:

spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa

9. Spring Data JPA 的有用工具

所有主要的 Java IDE 都支持 Spring Data JPA。让我们看看 Eclipse 和 IntelliJ IDEA 有哪些有用的工具。

**如果你使用 Eclipse 作为你的 IDE,你可以安装Dali Java Persistence Tools 插件。**这提供了 JPA 实体的 ER 图、用于初始化模式的 DDL 生成以及基本的逆向工程功能。此外,您还可以使用 Eclipse Spring Tool Suite (STS)。它将有助于验证 Spring Data JPA 存储库中的查询方法名称。

如果您使用 IntelliJ IDEA,有两个选项。

IntelliJ IDEA Ultimate 支持 ER 图、用于测试 JPQL 语句的 JPA 控制台和有价值的检查。但是,这些功能在 Community Edition 中不可用。

**为了提高 IntelliJ 的生产力,您可以安装JPA Buddy 插件,**它提供了许多功能,包括生成 JPA 实体、Spring Data JPA 存储库、DTO、初始化 DDL 脚本、Flyway 版本化迁移、Liquibase 更改日志等。此外,JPA Buddy 提供逆向工程的高级工具。

最后,JPA Buddy 插件适用于社区版和终极版。