下一篇[未完待续]
<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 注解的类都将被考虑。典型的实体类类似于以下示例:
<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 存储库接口定义:
<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>
<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 它,如下面示例所示:
<code>@Componentpublic class JooqExample implements CommandLineRunner { private final DSLContext create; @Autowired public JooqExample(DSLContext dslContext) { this.create = dslContext; }}/<code>
提示:jOOQ 手册倾向于使用一个名为 create 的变量来保存 DSLContext。
然后,你可以使用 DSLContext 来构造查询,如下面示例所示:
<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。
下一篇[未完待续]
閱讀更多 IT薺薺菜 的文章