SpringBoot中文参考指南(2.1.6)31.3、JPA 和 Spring Data JPA

下一篇[未完待续]

SpringBoot中文参考指南(2.1.6)31.3、JPA 和 Spring Data JPA

<code>英文原文:https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/boot-features-sql.html/<code>
<code>GitHub:https://github.com/jijicai/Spring/tree/master/spring-boot/<code>

31.3、JPA 和 Spring Data JPA

Java Persistence API 是一种标准技术,允许你将对象“映射”到关系数据库。spring-boot-starter-data-jpa POM 提供了快速入门的方法。它提供了以下关键依赖项:

(1)Hibernate:最流行的 JPA 实现之一。

(2)Spring Data JPA:使实现基于 JPA 的存储库变得容易。

(3)Spring ORMs:Spring Framework 的核心 ORM 支持。

提示:我们在这里不涉及太多 JPA 或 Spring Data 的细节。你可以遵循 spring.io 中的“使用 JPA 访问数据”指南,并阅读 Spring Data JPA 和 Hibernate 参考文档。(https://spring.io/guides/gs/accessing-data-jpa/ )

31.3.1、实体类

传统上,JPA“Entity”类是在 persistence.xml 文件中指定的。对于 Spring Boot,不需要这个文件,而是使用“Entity 扫描”。默认情况下,搜索主配置类(用 EnableAutoConfiguration 或 @SpringBootApplication 注解的包)下面的所有包。

任何用 @Entity、@Embeddable 或 @MappedSuperclass 注解的类都将被考虑。典型的实体类类似于以下示例:

SpringBoot中文参考指南(2.1.6)31.3、JPA 和 Spring Data JPA

<code>package com.example.myapp.domain;import java.io.Serializable;import javax.persistence.*;@Entitypublic class City implements Serializable {    @Id    @GeneratedValue    private Long id;    @Column(nullable = false)    private String name;    @Column(nullable = false)    private String state;    // ... additional members, often include @OneToMany mappings    protected City() {        // no-args constructor required by JPA spec        // this one is protected since it shouldn't be used directly    }    public City(String name, String state) {        this.name = name;        this.state = state;    }    public String getName() {        return this.name;    }    public String getState() {        return this.state;    }    // ... etc}/<code>

提示:你可以使用 @EntityScan 注解自定义实体扫描位置。参见第 84.4 节:将 @Entity 定义与 Spring 配置分离。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/howto-data-access.html#howto-separate-entity-definitions-from-spring-configuration )

31.3.2、Spring Data JPA 存储库

Spring Data JPA 存储库是可以定义来访问数据的接口。JPA 查询是根据方法名自动创建的。例如,CityRepository 接口可以声明 findAllByState(String state) 方法来查找给定状态下的所有城市。

对于更复杂的查询,可以使用 Spring Data 的 Query 注解来注解方法。

Spring Data 存储库通常从 Repository 或 CrudRepository 接口扩展。如果使用自动配置,则会从包含主配置类(用 @EnableAutoConfiguration 或 @SpringBootApplication 注解的配置类)的包中向下搜索存储库。

以下示例显示了典型的 Spring Data 存储库接口定义:

SpringBoot中文参考指南(2.1.6)31.3、JPA 和 Spring Data JPA

<code>package com.example.myapp.domain;import org.springframework.data.domain.*;import org.springframework.data.repository.*;public interface CityRepository extends Repository<city> {    Page<city> findAll(Pageable pageable);    City findByNameAndStateAllIgnoringCase(String name, String state);}/<city>/<city>/<code>

Spring Data JPA 存储库支持三种不同的引导模式:default、deferred 和 lazy。要启用 deferred 或 lazy,请分别将 spring.data.jpa.repositories.bootstrap-mode 设置为 deferred 或 lazy。使用 deferred 或 lazy 时,自动配置的 EntityManagerFactoryBuilder 将使用上下文的 AsynTaskExecutor(如果有)作为引导执行器。如果存在多个,将使用名为 applicationTaskExecutor 的名称。

提示:我们仅仅触及了 Spring Data JPA 的皮毛。有关完整的详细信息,请参阅 Spring Data JPA 参考文档。(https://docs.spring.io/spring-data/jpa/docs/current/reference/html/ )

31.3.3、创建和删除 JPA 数据库

默认情况下,只有在使用嵌入式数据库(H2、HSQL 或 Derby)时,才会自动创建 JPA 数据库。你可以使用 spring.jpa.* 属性显示地配置 JPA 设置。例如,要创建和删除表,可以将以下行添加到 application.properties:

<code>spring.jpa.hibernate.ddl-auto=create-drop/<code>

注释:Hibernate 自己的内部属性名(如果你记得更好的话)是 hibernate.hbm2ddl.auto。可以使用 spring.jpa.properties.*(在将它们添加到实体管理器之前去掉该前缀)将它与其他 Hibernate 自有属属性一起设置。下一行显示了为 Hibernate 设置 JPA 属性的示例。

<code>spring.jpa.properties.hibernate.globally_quoted_identifiers=true/<code>

上例中的行将 hibernate.globally_quoted_identifiers 属性的值 true 传递给 Hibernate 实体管理器。

默认情况下,DDL 执行(或验证)将延迟到 ApplicationContext 启动之后。还有一个 spring.jpa.generate-ddl 标志,但如果 Hibernate 自动配置处于活动状态,则不使用它,因为 ddl-auto 设置的粒度更细。

31.3.4、在 View 中打开 EntityManager

如果你正在运行一个 web 应用程序,则 Spring Boot 默认情况下会注册 OpenEntityManagerInViewIntercepter 来应用“在 View 中打开 EntityManager”模式,以允许在 web 视图中延迟加载。如果不希望这种行为,则应当在 application.properties 文件中将 spring.jpa.open-in-view 设置为 false。

31.4、Spring Data JDBC

Spring Data 包括对 JDBC 的存储库支持,并将自动为 CrudRepository 上的方法生成 SQL。对于更高级的查询,将提供 @Query 注解。

当必要的依赖项在类路径上时,Spring Boot 将自动配置 Spring Data 的 JDBC 存储库。它们可以通过对 spring-boot-starter-data-jdbc 的单个依赖关系添加到项目中。如果需要,你可以通过向应用程序添加 @EnableJdbcRepositories 注解或 JdbcConfiguration 子类来控制 Spring Data JDBC 的配置。

提示:有关 Spring Data JDBC 的完整详细信息,请参阅参考文档。

31.5、使用 H2 的 Web 控制台

H2 数据库提供了一个基于浏览器的控制台,Spring Boot 可以为你自动配置。当满足以下条件时,控制台将自动配置:

(1)你正在开发一个基于 servlet 的 web 应用程序。

(2)com.h2database:h2 在类路径上。

(3)你正在使用 Spring Boot 的开发者工具。

提示:如果你不使用 Spring Boot 的开发者工具,但仍希望使用 H2 的控制台,则可以使用 true 值配置 spring.h2.console.enabled 属性。

注释:H2 控制台仅在开发期间使用,因此应注意确保 spring.h2.console.enabled 在生产中不设置为 true。

31.5.1、更改 H2 控制台的路径

默认情况下,控制台在 /h2-console 上可用。可以使用spring.h2.console.path 属性自定义控制台的路径。

31.6、使用 jOOQ

jOOQ 面向对象查询(jOOQ)是 Data Geekery 的一个流行产品,并允许你通过其 fluent API 构建类型安全的 SQL 查询。商业版和开源版都可以与 Spring Boot 一起使用。

31.6.1、代码生成

为了使用 jOOQ 类型安全查询,需要从数据库模式生成 Java 类。你可以按照 jOOQ 用户手册中的说明进行操作。如果你使用 jooq-codegen-maven 插件,并且还使用 spring-boot-starter-parent“父级 POM”,则可以安全地省略该插件的 <version> 标记。你还可以使用 Spring Boot 定义的版本变量(例如:h2.version)来声明插件的数据库依赖项。下面的列表显示了一个示例:/<version>

SpringBoot中文参考指南(2.1.6)31.3、JPA 和 Spring Data JPA

<code><plugin>    <groupid>org.jooq/<groupid>    <artifactid>jooq-codegen-maven/<artifactid>    <executions>        ...    /<executions>    <dependencies>        <dependency>            <groupid>com.h2database/<groupid>            <artifactid>h2/<artifactid>            <version>${h2.version}/<version>        /<dependency>    /<dependencies>    <configuration>        <jdbc>            <driver>org.h2.Driver/<driver>            jdbc:h2:~/yourdatabase        /<jdbc>        <generator>            ...        /<generator>    /<configuration>/<plugin>/<code>

31.6.2、使用 DSL Context

jOOQ 提供的 fluent API 是通过 org.jooq.DSLContext 接口的启动的。Spring Boot 将 DSLContext 自动配置为 Spring Bean,并将其连接到应用程序 DataSource。要使用 DSLContext,可以 @Autowire 它,如下面示例所示:

SpringBoot中文参考指南(2.1.6)31.3、JPA 和 Spring Data JPA

<code>@Componentpublic class JooqExample implements CommandLineRunner {    private final DSLContext create;    @Autowired    public JooqExample(DSLContext dslContext) {        this.create = dslContext;    }}/<code>

提示:jOOQ 手册倾向于使用一个名为 create 的变量来保存 DSLContext。

然后,你可以使用 DSLContext 来构造查询,如下面示例所示:

SpringBoot中文参考指南(2.1.6)31.3、JPA 和 Spring Data JPA

<code>public List<gregoriancalendar> authorsBornAfter1980() {    return this.create.selectFrom(AUTHOR)        .where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1)))        .fetch(AUTHOR.DATE_OF_BIRTH);}/<gregoriancalendar>/<code>

31.6.3、jOOQ-SQL 方言

如果没有配置 spring.joog.sql-dialect 属性,则 Spring Boot 将确定用于数据源的 SQL 方言。如果 Spring Boot 无法检测到该方言,则使用默认值。

注释:Spring Boot 只能自动配置 jOOQ 开源版支持的方言。

31.6.4、自定义 jOOQ

可以通过定义自己的 @Bean 定义来实现更高级的定制,该定义在创建 jOOQ 配置时使用。可以为以下 jOOQ 类型定义 bean:

(1)ConnectionProvider

(2)ExecutorProvider

(3)TransactionProvider

(4)RecordMapperProvider

(5)RecordUnmapperProvider

(6)RecordListenerProvider

(7)ExecuteListenerProvider

(8)VisitListenerProvider

(9)TransactionListenerProvider

如果你想完全控制 jOOQ 配置,还可以创建自己的 org.jooq.Configuration @Bean。

下一篇[未完待续]


分享到:


相關文章: