1
0
mirror of https://github.com/apachecn/spring-boot-doc-zh.git synced 2025-06-06 17:50:57 +00:00
wizardforcel cdd1ca7535 mkdocs
2018-11-26 15:20:07 +08:00

12 KiB
Raw Permalink Blame History

29. 使用SQL数据库

Spring Framework 为使用SQL数据库提供了广泛的支持。 从使用JdbcTemplate直接JDBC访问到完成“对象关系映射”技术如Hibernate。Spring Data提供了额外的功能直接从接口创建Repository实现并使用约定从方法名称生成查询。

29.1 配置DataSource

Java的javax.sql.DataSource接口提供了使用数据库连接的标准方法。传统上DataSource使用URL和一些凭据来建立数据库连接。

还可以查看更多高级示例的“操作方法”部分通常可以完全控制DataSource的配置。

29.1.1 嵌入式数据库支持

使用内存中嵌入式数据库开发应用程序通常很方便。 显然,内存数据库不提供持久化存储; 您的应用程序启动时,您将需要初始化数据库,并在应用程序结束时丢弃数据。

“How-to”部分包含如何初始化数据库

Spring Boot可以自动配置嵌入式 H2HSQL 和 Derby 数据库。 您不需要提供任何连接URL只需将要使用的嵌入式数据库的依赖关系包含进去即可。

如果您在测试中使用此功能,您可能会注意到,整个测试套件都会重复使用相同的数据库,而不管您使用的应用程序上下文的数量。 如果要确保每个上下文都有一个单独的嵌入式数据库您应该将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>

对于要自动配置的嵌入式数据库您需要依赖spring-jdbc。 在这个例子中它是通过spring-boot-starter-data-jpa传递的。

如果由于某种原因配置嵌入式数据库的连接URL则应注意确保数据库的自动关闭被禁用。 如果你使用H2你应该使用DB_CLOSE_ON_EXIT=FALSE这样做。 如果您使用HSQLDB则应确保不使用shutdown=true。 禁用数据库的自动关闭允许Spring Boot控制数据库何时关闭从而确保在不再需要访问数据库时发生这种情况。

29.1.2 连接到生产环境数据库

生产数据库连接也可以使用连接池数据源自动配置。 这是选择具体实现的算法:

  • 我们更喜欢Tomcat连接池DataSource的性能和并发性所以如果可用我们总是选择它。
  • 否则如果HikariCP可用我们将使用它。
  • 如果Tomcat池数据源和HikariCP都不可用并且如果Commons DBCP可用我们将使用它但是我们不建议在生产中使用它并且不支持它。
  • 最后如果Commons DBCP2可用我们将使用它。

如果您使用spring-boot-starter-jdbc或spring-boot-starter-data-jpa 的startters您将自动获得对tomcat-jdbc的依赖。

您可以完全绕过该算法并通过spring.datasource.type属性指定要使用的连接池。 如果您在Tomcat容器中运行应用程序则默认情况下提供tomcat-jdbc这一点尤为重要。

可以随时手动配置其他连接池。如果您定义自己的DataSource bean则不会发生自动配置。

DataSource配置由spring.datasource中的外部配置属性控制。 例如您可以在application.properties中声明以下部分

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

您应至少使用spring.datasource.url属性指定url否则Spring Boot将尝试自动配置嵌入式数据库。

您通常不需要指定驱动程序类名称因为Spring Boot可以从url为大多数数据库推断出驱动程序名称。

对于要创建的池数据源我们需要能够验证有效的Driver类是否可用所以我们在做任何事情之前检查它。 即 如果您设置spring.datasource.driver-class-name=com.mysql.jdbc.Driver那么该类必须可加载。

有关更多支持的选项,请参阅 DataSourceProperties。 这些是标准选项,无论实际执行情况如何。 还可以使用各自的前缀spring.datasource.tomcat.*spring.datasource.hikari.和spring.datasource.dbcp2.)微调实现特定的设置。 有关更多详细信息,请参阅您正在使用的连接池实现的文档。

例如如果您正在使用Tomcat连接池您可以自定义许多其他设置

# 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 DataSource

如果要将Spring Boot应用程序部署到应用程序服务器则可能需要使用应用程序服务器内置功能来配置和管理DataSource并使用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 使用JdbcTemplate

Spring的JdbcTemplate和NamedParameterJdbcTemplate类是自动配置的您可以将它们直接连接到您自己的bean中

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public MyBean(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    // ...

}

29.3 JPA 和 Spring Data

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

  • Hibernate - 最受欢迎的JPA实现之一。
  • Spring Data JPA - 可以轻松实现基于JPA的存储库。
  • Spring ORMs - 来自Spring Framework的核心ORM支持。

我们不会在这里介绍太多的JPA或Spring Data的细节。 您可以从spring.io中查看“使用JPA访问数据”指南,并阅读Spring Data JPAHibernate参考文档。

默认情况下Spring Boot使用Hibernate 5.0.x. 但是如果您愿意也可以使用4.3.x或5.2.x。 请参考 Hibernate 4 和 Hibernate 5.2 示例,看看如何做到这一点。

29.3.1 实体类

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

任何用@Entity@Embeddable或@MappedSuperclass注解的类将被考虑。 典型的实体类将如下所示:

package com.example.myapp.domain;

import java.io.Serializable;
import javax.persistence.*;

@Entity
public 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

}

您可以使用@EntityScan注解自定义实体扫描位置。 请参见第77.4节“从Spring配置中分离@Entity定义”操作方法。

29.3.2 Spring Data JPA Repositories

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

对于更复杂的查询您可以使用Spring数据查询注解来注解您的方法。

Spring数据存储库通常从Repository或CrudRepository接口扩展。 如果您正在使用自动配置,将从包含主配置类(通过@EnableAutoConfiguration或@SpringBootApplication注解的包的包中搜索存储库(repositories)。

这是一个典型的Spring数据库

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

}

我们只是触及了Spring Data JPA的表面。 有关完整的详细信息,请查阅其参考文档

29.3.3 创建和删除JPA数据库

默认情况下仅当您使用嵌入式数据库H2HSQL或Derby时才会自动创建JPA数据库。 您可以使用spring.jpa。*属性显式配置JPA设置。 例如要创建和删除表您可以将以下内容添加到application.properties中。