【周一通勤电台】Spring Data JPA 极速入门

Hello,大家好,这里是翊君@周一通勤电台频道。

0.阅读完本文你将会学会

  • 如何在Spring项目中引入Spring Data JPA

本文一共约1800读时长大概等于一首黑眼豆豆的《Where Is The Love?》

1. 概述

这篇文章将重点介绍如何在Spring项目中引入Spring Data JPA,并全面配置持久化层。

2.Spring Data生成的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命名查询定义自定义查询

第三个选项,Specification和Querydsl支持,类似于JPA标准,但使用更灵活和方便的API。这使得整个操作的可读性和可重用性大大增强。在处理大量的固定查询时,这种API的优势将变得更加明显,因为我们有可能通过数量较少的可重用代码块来更简洁地表达这些查询。

最后一种方案的缺点是,它要么涉及到XML,要么让实体类承担查询的负担。

3.1 自动的自定义查询

当Spring Data创建一个新的Repository实现时,它分析了所有由接口定义的方法,并试图从方法名称中自动生成查询。虽然这有一些局限性,但这是一种非常强大和优雅的方式,只需少量工作就可以定义新的自定义访问方法。

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

public interface IFooDAO extends JpaRepository<Foo, Long> {

    Foo findByName(String name);

}
复制代码

这是一个相对简单的例子。查询创建机制支持更多的关键词:

如果解析器不能将该属性与域对象字段相匹配,我们会看到以下异常。

java.lang.IllegalArgumentException: No property nam found for type class com.jayxu.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,它使用注解定义了事务语义。

更明确地说,这在类的层面上使用了一个只读的@Transactional注解,然后对非只读的方法进行重写。其余的事务语义是默认的,但这些可以很容易地被每个方法手动重写。

4.1 异常转译仍然是ok的

在Java中,我们通常使用try-catch语句捕获异常,进行异常处理。但有些时候,我们使用try-catch捕获一个异常,但却不进行异常处理,反而是抛出另一个异常,这就称为异常转译。

现在的问题是:由于Spring Data JPA不依赖于旧的ORM模板(JpaTemplate、HibernateTemplate),而且它们从Spring 5开始就被删除了,我们是否还能让我们的JPA异常被翻译成Spring的DataAccessException层次结构?

答案是,我们当然要这样做。通过在DAO上使用@Repository注解,仍然可以实现异常转译。这个注解使Spring Bean后理器能够用容器中发现的所有PersistenceExceptionTranslator实例告知所有@Repository Bean,并像以前一样提供异常转译。

让我们用一个集成测试来验证异常转译。

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

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

5.Spring Data JPA Repository配置

为了激活Spring JPA repository的支持,我们可以使用@EnableJpaRepositories注解并指定包含DAO接口的包。

@EnableJpaRepositories(basePackages = "com.jayxu.spring.data.persistence.repository") 
public class PersistenceConfig { 
    ...
}
复制代码

我们可以用XML配置做同样的事情。

<jpa:repositories base-package="com.jayxu.spring.data.persistence.repository" />
复制代码

6.Java或XML配置

我们将会在新的的文章中详细讨论如何在Spring中配置JPA。Spring Data还利用了Spring对JPA @PersistenceContext注解的支持。它利用这一点将EntityManager连接到负责创建实际DAO实现的Spring工厂Bean(JpaRepositoryFactoryBean)。

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

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

7.Maven的依赖性

除了Maven对JPA的配置外,我们还需要添加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依赖,它将自动为我们配置数据源。 我们需要确保我们要使用的数据库存在于classpath中。在我们的例子中,我们已经添加了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文件中的属性来做到这一点。

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

在这个例子中,我们改变了连接的URL和用户名密码。

9.结语

在这篇文章中,我们使用XML和基于Java的配置,介绍了Spring Data JPA的持久层的配置和实现。 我们讨论了如何定义更高级的自定义查询,以及事务和新jpa命名空间的配置。现在Spring可以以一种崭新的、优雅的方式进行数据访问,快试试吧。

感谢收看本期的翊君@周一通勤电台。如果你觉得还不错的话,快给我三连支持一下吧,咱们下期不见不散呐。

Supongo que te gusta

Origin juejin.im/post/7049133266351161375
Recomendado
Clasificación