Spring Data JPA 极速入门

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可以以一种崭新的、优雅的方式进行数据访问,快试试吧。

全部评论

相关推荐

06-27 12:54
已编辑
门头沟学院 Java
累了,讲讲我的大学经历吧,目前在家待业。我是一个二本院校软件工程专业。最开始选专业是觉得计算机感兴趣,所以选择了他。本人学习计算机是从大二暑假结束开始的,也就是大三开始。当时每天学习,我个人认为Java以及是我生活的一部分了,就这样持续学习了一年半,来到了大四上学期末,大概是在12月中旬,我终于找的到了一家上海中厂的实习,但我发现实习生的工作很枯燥,公司分配的活也不多,大多时间也是自己在自学。就这样我秋招末才找到实习。时间来到了3月中旬,公司说我可以转正,但是转正工资只有7000,不过很稳定,不加班,双休,因为要回学校参加答辩了,同时当时也是心高气傲,认为可以找到更好的,所以放弃了转正机会,回学校准备论文。准备论文期间就也没有投递简历。然后时间来到了5月中旬,这时春招基本也结束了,然后我开始投递简历,期间只是约到了几家下场面试。工资也只有6-7k,到现在我不知道该怎么办了。已经没有当初学习的心劲了,好累呀,但是又不知道该干什么去。在家就是打游戏,boss简历投一投。每天日重一次。26秋招都说是针对26届的人,25怎么办。我好绝望。要不要参加考公、考研、央国企这些的。有没有大佬可以帮帮我。为什么感觉别人找工作都是顺其自然的事情,我感觉自己每一步都在艰难追赶。八股文背了又忘背了又忘,我每次都花很长时间去理解他,可是现在感觉八股、项目都忘完了。真的已经没有力气再去学习了。图片是我的简历,有没有大哥可以指正一下,或者说我应该走哪条路,有点不想在找工作了。
码客明:太累了就休息一下兄弟,人生不会完蛋的
如果实习可以转正,你会不...
点赞 评论 收藏
分享
积极的小学生不要香菜:你才沟通多少,没500不要说难
点赞 评论 收藏
分享
投递OPPO等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务