SpringBoot 中文手册 --Part IV --29 使用SQL数据库

来源:互联网 发布:js 关键字 编辑:程序博客网 时间:2024/06/05 08:34

本文翻译自 https://docs.spring.io/spring-boot/docs/1.5.7.RELEASE/reference/htmlsingle/#boot-features-sql

受个人水平有限,部分翻译可能不正确,欢迎指正。


29.使用SQL数据库

Spring 框架提供了对使用SQL数据库提供了大量支持。使用 JdbcTemplate 直接访问JDBC完成“对象关系映射”技术如Hibernate。Spring Data提供额外的方法级标准,可以直接从接口创建 Repository实现,并使用惯例从你的方法名上来生成查询。


29.1 配置一个数据源

Java的 javax.sql.DataSource 接口提供了一个使用数据库连接工作的标准方法。通常一个数据源使用一个带有一些带有凭证的 URL 来建立一个数据库连接。

[Tip]

也可检查 “怎么做”章节 获得更多高级使用例子,代表了通过数据源配置获得完全控制。


29.1.1 内部数据库支持

通常使用一个内存嵌入式的数据库来开发一个应用很方便。显然,内存型数据库不提供持久存储;你需要在你的应用启动时构建数据库,并做好当你的应用关闭后丢失数据。


[Tip]

这“怎么做”章节包含一个 关于如何初始化一个数据库的章节



Spring Boot可以自动配置内部的H2,HSQL和Derby 数据库。你不需要提供任何链接的URLs,只需简单的将你想使用的内部数据库的构建依赖加入即可。


[Note]

如果你在测试时使用这个特性,你可能会注意到你的这个测试套件不管你是用多少个应用上下文都会使用相同的数据库。如果你想确保每一个上下文都有一个单独的内部数据库,你需要设置 spring.datasource.generate-unique-name 为true 。


例如,典型的POM依赖将会是:

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency>    <groupId>org.hsqldb</groupId>    <artifactId>hsqldb</artifactId>    <scope>runtime</scope></dependency>

[Note]

你需要一个关于 spring-jdbc 的依赖来让一个内部数据库被自动配置。在这个例子中,它通过spring-boot-starter-data-jpa 来及时拉取。

[Tip]

假如无论什么原因,你想给一个内嵌的数据库配置URL连接,要十分小心确保数据库的自动关闭是禁用的。如果你在使用H2 你应该使用 DB_CLOSE_ON_EXIT=FALSE 来操作。如果你在使用HSQLDB,你需要确保 shutdown=true 没有使用。禁用数据库的自动关机可以让Spring Boot来控制数据库何时关闭,从而确保不再需要访问数据库时可以关闭数据库。

29.1.2 连接到生产数据库

生产数据库连接可以通过使用 DataSource. 池来自动配置。这是选择特殊实现的算法:

  • 我们更愿意使用Tomcat的 DataSource 池因为它的高性能和高并发,所以如果可能,我们会一直选择它。
  • 否则,如果HikariCP 可用我们则使用它。
  • 如果Tomcat 数据源池和HikariCP不可用时,通用DBCP可用,我们会使用DBCP,但我们不建议在生产环境使用它,因为它不好做支持。
  • 最后,如果通用 DBCP2可用,我们会使用它;
如果你使用 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa 起步你将自动获得 tomcat-jdbc的依赖。

[Note]

你可以通过使用 spring.datasource.type 属性忽略算法完成来指定连接池.如果你在Tomcat容器中运行你的应用,这一点尤为重要,因为默认提供了 tomcat-jdbc

[Tip]

额外的连接池一直可以手动配置。如果定义了自己的DataSource bean,自动配置就不会出现。

数据源配置被spring.datasource.* 下的外部配置属性控制。例如,你可能在application.properties 中声明了下面的部分:

spring.datasource.url=jdbc:mysql://localhost/testspring.datasource.username=dbuserspring.datasource.password=dbpassspring.datasource.driver-class-name=com.mysql.jdbc.Driver

[Note]

你至少应指定 spring.datasource.url 属性否则 Spring Boot 会尝试自动配置一个内部的数据库。

[Tip]

你通常不需要指定 driver-class-name 因为Spring boot可以从 url 中推断出大多数数据库的驱动名

[Note]

对于要创建的 DataSource 池我们需要能够验证一个合法的Driver 类可获得以便我们在做其他事之前验证。换言之,你设置了spring.datasource.driver-class-name=com.mysql.jdbc.Driver 那么这个类应该被加载了

查看 DataSourceProperties 获得更多操作支持。标准操作是不管具体实现细节的。使用它们各自前缀(spring.datasource.tomcat.*,spring.datasource.hikari.*, 和spring.datasource.dbcp2.*) 的设置也可以很好的实现指定功能。查阅你正在使用的连接池实现文档获得更多细节。


例如,假如你在使用 Tomcat connection pool 你可以定制很多额外配置:

# Number of ms to wait before throwing an exception if no connection is available.spring.datasource.tomcat.max-wait=10000# Maximum number of active connections that can be allocated from this pool at the same time.spring.datasource.tomcat.max-active=50# Validate the connection before borrowing it from the pool.spring.datasource.tomcat.test-on-borrow=true

29.1.3 连接到JNDI数据库

如果你正在发布你的Spring Boot应用到应用服务器,你可能想使用应用服务器的BUILT-IN特性来配置和管理你的数据源,且允许它使用JNDI。


这个 spring.datasource.jndi-name 属性可以用作spring.datasource.urlspring.datasource.username 和

spring.datasource.password  属性的替代,来从一个指定的JNDI位置访问 DataSource 。例如,在 application.properties 中

下面这部分显示了你可以允许一个JBoss AS当做  DataSource:

spring.datasource.jndi-name=java:jboss/datasources/customers

29.2 使用JDBC 模板

Spring的JdbcTemplate 和NamedParameterJdbcTemplate 类是自动配置的,你可以直接 @Autowire 他们到你自己的beans中:

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Component;@Componentpublic class MyBean {    private final JdbcTemplate jdbcTemplate;    @Autowired    public MyBean(JdbcTemplate jdbcTemplate) {        this.jdbcTemplate = jdbcTemplate;    }    // ...}

29.3 JPA和“Spring Data”

Java持久API 是一个标准技术允许你映射对象到关系型数据库。 spring-boot-starter-data-jpa POM提供了快速起步的方式,它提供下列关键依赖:

  • Hibernate --最受流行的JPA实现。
  • Spring Data JPA -- 使基于JPA原型的实现变得简单
  • Spring ORMs--Spring框架的ORM核心支持
[Tip]

这里我们不会讲JPA和Spring Data 的过多细节。你可以从 spring.io上的‘Accessing Data with JPA’ 引导 和阅读Spring Data JPA 和Hibernate 参考文档。

[Note]

默认 Spring Boot 使用Hibernate 5.0.x。然后如果你希望使用 4.3.x or 5.2.x 也是可能的。请根据 Hibernate 4 和 Hibernate 5.2 样例来看具体怎么操作。

29.3.1 实体类

通常来讲,JPA实体类被指定在一个 persistence.xml 文件中。使用Spring Boot不需要这个文件,取而代之使用了“实体扫描”。默认你主配置类( @EnableAutoConfiguration 或@SpringBootApplication 注解的类)下的所有包都会被查找。

所有被 @Entity@Embeddable 或 @MappedSuperclass 注解的类都被考虑在内。一个典型的实体类可能像这样:
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.country = country;    }    public String getName() {        return this.name;    }    public String getState() {        return this.state;    }    // ... etc}

[Tip]

你可以使用 @EntityScan 注解定义实体扫描位置。 查看 Section 77.4, “Separate @Entity definitions from Spring configuration” 如何操作.


29.3.2 Spring Data JPA 原型

Spring Data JPA原型是你可以定义访问数据的接口。根据你的方法名自动创建JPA查询。例如,一个CityRepository 接口可能声明

成一个 findAllByState(String state) 方法来查找一个给定州下的所有城市。

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

Spring Data原型通常继承自 Repository or CrudRepository 接口。如果你使用自动配置,原型将在包含你主配置类(

 @EnableAutoConfiguration 或@SpringBootApplication 注解类)的包下查找。

这是一个Spring Data原型的典型例子:

package com.example.myapp.domain;import org.springframework.data.domain.*;import org.springframework.data.repository.*;public interface CityRepository extends Repository<City, Long> {    Page<City> findAll(Pageable pageable);    City findByNameAndCountryAllIgnoringCase(String name, String country);}
[Tip]

我们仅给出Spring Data JPA表层 更多细节查阅他们的 reference documentation.


29.3.3 创建和销毁 JPA数据库

通常,JPA数据库仅在你使用内部数据库(H2, HSQL or Derby)时自动创建。你可以使用 spring.jpa.* 属性明确地配置JPA设置。

例如,要创建和删除表,你可以增加下列到你的application.properties

spring.jpa.hibernate.ddl-auto=create-drop
[Note]

在Hibernate内部,属性名 (如果你恰好记得) 是hibernate.hbm2ddl.auto. 你可以用 spring.jpa.properties.* (前缀需要在加入实体管理时去除)来设置,或其他原生属性. 例如:

spring.jpa.properties.hibernate.globally_quoted_identifiers=true
传递 hibernate.globally_quoted_identifiers 给Hibernate实体管理。

默认DDL执行(或确认)或延迟到 ApplicationContext 启动。配置中也有 spring.jpa.generate-ddl 标志,但是如果Hibernate

自动配置是激活时是不可用的,因为 ddl-auto 设置更详细。


29.3.4 在视图中打开 实体管理器

当你运行一个web应用时,Spring Boot默认注册OpenEntityManagerInViewInterceptor  来应用“在视图中打开实体管理器”模式,

即允许在WEB视图中懒加载。如果你不需要此行为,你可以在你的 application.properties 的中设置spring.jpa.open-in-view 为 false 


29.4 使用H2的WEB 控制台

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

  • 你在开发一个WEB应用
  • com.h2database:h2 在classpath中
  • 你在使用Spring Boot开发工具
[Tip]

如果你没有使用Spring Boot开发工具,但你仍想使用H2的控制台,你可以通过设置 spring.h2.console.enabled属性为 true 。 H2 控制台仅用于开发期间所欲确保 spring.h2.console.enabled 在生产环境没有设置为 true 。


29.4.1 改变H2控制台路径

默认通过 /h2-console 获得控制台。你可以使用 spring.h2.console.path 属性自定义控制台路径。


29.4.2 保护H2控制台

当Spring Security在类路径且基本认证开启,那么H2控制台将自动使用基本认证保护。下面的属性可以用来自定义安全配置:

  • security.user.role
  • security.basic.authorize-mode
  • security.basic.enabled


29.5 使用JOOQ

Java Object Oriented Querying (jOOQ) 是一个来自Data Geekery 的广受欢迎的产品,可以根据你的数据库来生成Java代码,

并且让你通过它的流式API构建安全的SQL查询。商业版和开源社区版都可以和Spring Boot一起使用。


29.5.1 代码生成

为了使用jOOQ的安全查询,你需要从你的数据库模式定义中生成Java类。你可以按jOOQ user manual 说明做。如果你在使

jooq-codegen-maven 插件(并且你使用 spring-boot-starter-parent  “父POM”)你可以放心的省略插件的 <version> 。

你也可以使用Spring Boot定义版本变量(例如  h2.version )来声明插件的数据库依赖。这是一个例子:

<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>            <url>jdbc:h2:~/yourdatabase</url>        </jdbc>        <generator>            ...        </generator>    </configuration></plugin>

29.5.2 使用DSLContext

jOOQ提供的流式API通过 org.jooq.DSLContext 接口初始化。Spring Boot自动配置 DSLContext 作为一个Spring的bean,

把它和你的应用DataSource 关联起来。要使用 DSLContext  你只需 @Autowire 它:

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

[Tip]

 jOOQ 手册趋向于使用一个名为 create 的变量来处理 DSLContext ,我们在上述例子中就这样做了


随后你可以使用 DSLContext 来构造你的查询:

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);}

29.5.3 自定义jOOQ

你可以给jOOQ通过在你的application.properties 中设置 spring.jooq.sql-dialect 指定SQL 方言。例如,指定Postgres :

spring.jooq.sql-dialect=Postgres
更多高级定制可以通过定义自己的在jOOQ Configuration 创建时使用的 @Bean 定义完成。你可以定义下列jOOQ类型的bean:

  • ConnectionProvider
  • TransactionProvider
  • RecordMapperProvider
  • RecordListenerProvider
  • ExecuteListenerProvider
  • VisitListenerProvider
如需获得完全的jOOQ配置控制,你也可以创建你自己的  org.jooq.Configuration @Bean 。






原创粉丝点击