Spring Boot集成了许多数据技术,包括SQL和NoSQL。

1. SQL 数据库

Spring Framework提供了广泛的支持,用于与SQL数据库进行交互,从直接使用JdbcClientJdbcTemplate进行JDBC访问,到完整的“对象关系映射”技术,如Hibernate。Spring Data提供了额外的功能层次:直接从接口创建Repository实现,并使用约定从您的方法名称生成查询。

1.1. 配置数据源

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

查看“如何”部分以获取更高级的示例,通常用于完全控制数据源的配置。

1.1.1. 嵌入式数据库支持

通常通过使用内存中的嵌入式数据库来开发应用程序非常方便。显然,内存数据库不提供持久存储。您需要在应用程序启动时填充数据库,并准备在应用程序结束时丢弃数据。

“如何”部分包括有关如何初始化数据库的部分

Spring Boot可以自动配置嵌入式H2HSQLDerby数据库。您无需提供任何连接URL。您只需要包含要使用的嵌入式数据库的构建依赖项。如果类路径上有多个嵌入式数据库,则设置spring.datasource.embedded-database-connection配置属性以控制使用哪个。将该属性设置为none会禁用嵌入式数据库的自动配置。

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

1.1.2. 连接到生产数据库

生产数据库连接也可以通过使用池化DataSource进行自动配置。

1.1.3. 数据源配置

数据源配置由spring.datasource.*中的外部配置属性控制。例如,您可以在application.properties中声明以下部分:

属性
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
Yaml
spring:
  datasource:
    url: "jdbc:mysql://localhost/test"
    username: "dbuser"
    password: "dbpass"
您至少应通过设置spring.datasource.url属性来指定URL。否则,Spring Boot会尝试自动配置嵌入式数据库。
Spring Boot可以根据URL从大多数数据库中推断出JDBC驱动程序类。如果需要指定特定类,可以使用spring.datasource.driver-class-name属性。
要创建池化DataSource,我们需要能够验证是否有有效的Driver类可用,因此在执行任何操作之前我们会检查这一点。换句话说,如果您设置了spring.datasource.driver-class-name=com.mysql.jdbc.Driver,那么该类必须可加载。

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

例如,如果您使用Tomcat连接池,您可以自定义许多其他设置,如以下示例所示:

属性
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.test-on-borrow=true
Yaml
spring:
  datasource:
    tomcat:
      max-wait: 10000
      max-active: 50
      test-on-borrow: true

这将设置池在等待10000毫秒后抛出异常(如果没有可用连接),将最大连接数限制为50,并在从池中借用连接之前验证连接。

1.1.4. 支持的连接池

Spring Boot使用以下算法选择特定的实现:

  1. 我们偏好HikariCP,因为它具有良好的性能和并发性。如果HikariCP可用,我们总是选择它。

  2. 否则,如果Tomcat池化DataSource可用,我们将使用它。

  3. 否则,如果 Commons DBCP2可用,我们将使用它。

  4. 如果HikariCP、Tomcat和DBCP2都不可用,且Oracle UCP可用,则我们将使用它。

如果您使用spring-boot-starter-jdbcspring-boot-starter-data-jpa“starters”,则自动获取对HikariCP的依赖。

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

始终可以手动配置其他连接池,使用DataSourceBuilder。如果定义自己的DataSource bean,则不会发生自动配置。DataSourceBuilder支持以下连接池:

  • HikariCP

  • Tomcat池化Datasource

  • Commons DBCP2

  • Oracle UCP和OracleDataSource

  • Spring Framework的SimpleDriverDataSource

  • H2 JdbcDataSource

  • PostgreSQL PGSimpleDataSource

  • C3P0

1.1.5. 连接到JNDI数据源

如果您将Spring Boot应用部署到应用服务器,您可能希望通过使用应用服务器内置的功能来配置和管理您的数据源,并通过使用JNDI访问它。

spring.datasource.jndi-name属性可用作访问特定JNDI位置中的DataSource的替代方法,而不是使用spring.datasource.urlspring.datasource.usernamespring.datasource.password属性。例如,application.properties中的以下部分显示了如何访问JBoss AS定义的DataSource

属性
spring.datasource.jndi-name=java:jboss/datasources/customers
Yaml
spring:
  datasource:
    jndi-name: "java:jboss/datasources/customers"

1.2. 使用 JdbcTemplate

Spring的JdbcTemplateNamedParameterJdbcTemplate类是自动配置的,您可以直接将它们@Autowire到您自己的bean中,如下例所示:

Java
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final JdbcTemplate jdbcTemplate;

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

    public void doSomething() {
        this.jdbcTemplate ...
    }

}
Kotlin
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.stereotype.Component

@Component
class MyBean(private val jdbcTemplate: JdbcTemplate) {

    fun doSomething() {
        jdbcTemplate.execute("delete from customer")
    }

}

您可以通过使用spring.jdbc.template.*属性来自定义模板的一些属性,如下例所示:

属性
spring.jdbc.template.max-rows=500
Yaml
spring:
  jdbc:
    template:
      max-rows: 500
NamedParameterJdbcTemplate在后台重用相同的JdbcTemplate实例。如果定义了多个JdbcTemplate且没有主要候选项存在,则不会自动配置NamedParameterJdbcTemplate

1.3. 使用 JdbcClient

Spring的JdbcClient是基于NamedParameterJdbcTemplate的存在而自动配置的。您也可以直接将其注入到您自己的bean中,如下例所示:

Java
import org.springframework.jdbc.core.simple.JdbcClient;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final JdbcClient jdbcClient;

    public MyBean(JdbcClient jdbcClient) {
        this.jdbcClient = jdbcClient;
    }

    public void doSomething() {
        this.jdbcClient ...
    }

}
Kotlin
import org.springframework.jdbc.core.simple.JdbcClient
import org.springframework.stereotype.Component

@Component
class MyBean(private val jdbcClient: JdbcClient) {

    fun doSomething() {
        jdbcClient.sql("delete from customer").update()
    }

}

如果依赖自动配置来创建底层的JdbcTemplate,则在客户端中也会考虑使用spring.jdbc.template.*属性进行任何自定义。

1.4. JPA和Spring Data JPA

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

  • Hibernate:最流行的JPA实现之一。

  • Spring Data JPA:帮助您实现基于JPA的存储库。

  • Spring ORM:来自Spring Framework的核心ORM支持。

我们在这里不会深入讨论JPA或 Spring Data。您可以查看来自 “使用JPA访问数据”指南以及 Spring Data JPAHibernate 参考文档。

1.4.1. 实体类

传统上,JPA“实体”类在一个 persistence.xml 文件中指定。在Spring Boot中,这个文件是不必要的,而是使用“实体扫描”。默认情况下,会扫描 自动配置包

任何带有 @Entity@Embeddable@MappedSuperclass 注解的类都会被视为实体类。典型的实体类如下所示:

Java
import java.io.Serializable;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;

@Entity
public class City implements Serializable {

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String state;

    // ... 其他成员,通常包括 @OneToMany 映射

    protected City() {
        // JPA规范要求的无参构造函数
        // 这个受保护的构造函数不应直接使用
    }

    public City(String name, String state) {
        this.name = name;
        this.state = state;
    }

    public String getName() {
        return this.name;
    }

    public String getState() {
        return this.state;
    }

    // ... 等等

}
Kotlin
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.Id
import java.io.Serializable

@Entity
class City : Serializable {

    @Id
    @GeneratedValue
    private val id: Long? = null

    @Column(nullable = false)
    var name: String? = null
        private set

    // ... 等等
    @Column(nullable = false)
    var state: String? = null
        private set

    // ... 其他成员,通常包括 @OneToMany 映射

    protected constructor() {
        // JPA规范要求的无参构造函数
        // 这个受保护的构造函数不应直接使用
    }

    constructor(name: String?, state: String?) {
        this.name = name
        this.state = state
    }

}
您可以使用 @EntityScan 注解自定义实体扫描位置。请参阅“howto.html”中的操作说明。

1.4.2. Spring Data JPA存储库

Spring Data JPA 存储库是您可以定义用于访问数据的接口。JPA查询会根据您的方法名称自动生成。例如,一个 CityRepository 接口可能声明一个 findAllByState(String state) 方法来查找给定州中的所有城市。

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

Spring Data存储库通常扩展自 RepositoryCrudRepository 接口。如果使用自动配置,将搜索 自动配置包 中的存储库。

您可以使用 @EnableJpaRepositories 自定义要查找存储库的位置。

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

Java
import org.springframework.boot.docs.data.sql.jpaandspringdata.entityclasses.City;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;

public interface CityRepository extends Repository<City, Long> {

    Page<City> findAll(Pageable pageable);

    City findByNameAndStateAllIgnoringCase(String name, String state);

}
Kotlin
import org.springframework.boot.docs.data.sql.jpaandspringdata.entityclasses.City
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.repository.Repository

interface CityRepository : Repository<City?, Long?> {

    fun findAll(pageable: Pageable?): Page<City?>?

    fun findByNameAndStateAllIgnoringCase(name: String?, state: String?): City?

}

Spring Data JPA存储库支持三种不同的引导模式:默认、延迟和懒加载。要启用延迟或懒加载引导,将 spring.data.jpa.repositories.bootstrap-mode 属性设置为 deferredlazy。在使用延迟或懒加载引导时,自动配置的 EntityManagerFactoryBuilder 将使用上下文的 AsyncTaskExecutor(如果有的话)作为引导执行器。如果存在多个,则将使用名为 applicationTaskExecutor 的执行器。

在使用延迟或懒加载引导时,请确保在应用程序上下文引导阶段之后延迟访问JPA基础设施。您可以使用 SmartInitializingSingleton 来调用需要JPA基础设施的任何初始化。对于作为Spring bean创建的JPA组件(如转换器),如果有任何依赖关系,请使用 ObjectProvider 延迟解析。

我们只是浅尝辄止Spring Data JPA的功能。要获取完整详情,请参阅 Spring Data JPA参考文档

1.4.3. Spring Data Envers Repositories

如果Spring Data Envers可用,则JPA存储库会自动配置以支持典型的Envers查询。

要使用Spring Data Envers,请确保您的存储库扩展自RevisionRepository,如下例所示:

Java
import org.springframework.boot.docs.data.sql.jpaandspringdata.entityclasses.Country;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.history.RevisionRepository;

public interface CountryRepository extends RevisionRepository<Country, Long, Integer>, Repository<Country, Long> {

    Page<Country> findAll(Pageable pageable);

}
Kotlin
import org.springframework.boot.docs.data.sql.jpaandspringdata.entityclasses.Country
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.repository.Repository
import org.springframework.data.repository.history.RevisionRepository

interface CountryRepository :
        RevisionRepository<Country?, Long?, Int>,
        Repository<Country?, Long?> {

    fun findAll(pageable: Pageable?): Page<Country?>?

}
有关更多详细信息,请查看Spring Data Envers参考文档

1.4.4. 创建和删除JPA数据库

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

属性
spring.jpa.hibernate.ddl-auto=create-drop
Yaml
spring:
  jpa:
    hibernate.ddl-auto: "create-drop"
Hibernate自己的此属性的内部名称(如果您更容易记住)是hibernate.hbm2ddl.auto。您可以通过使用spring.jpa.properties.*(在添加到实体管理器之前会去除前缀)设置它,以及其他Hibernate本机属性。以下行显示了为Hibernate设置JPA属性的示例:
属性
spring.jpa.properties.hibernate[globally_quoted_identifiers]=true
Yaml
spring:
  jpa:
    properties:
      hibernate:
        "globally_quoted_identifiers": "true"

在上面的示例中,该行将hibernate.globally_quoted_identifiers属性的值设置为true,传递给Hibernate实体管理器。

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

1.4.5. 在视图中打开EntityManager

如果您运行Web应用程序,Spring Boot默认会注册OpenEntityManagerInViewInterceptor以应用“在视图中打开EntityManager”模式,以允许在Web视图中进行延迟加载。如果您不希望这种行为,应该在application.properties中将spring.jpa.open-in-view设置为false

1.5. Spring Data JDBC

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

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

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

1.6. 使用H2的Web控制台

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

如果您没有使用Spring Boot的开发人员工具,但仍希望使用H2的控制台,可以将spring.h2.console.enabled属性配置为true
H2控制台仅用于开发过程中使用,因此应确保在生产环境中不将spring.h2.console.enabled设置为true

1.6.1. 更改H2控制台的路径

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

1.6.2. 在受保护的应用程序中访问H2控制台

H2控制台使用框架,并且由于仅用于开发,因此不实现CSRF保护措施。如果您的应用程序使用Spring Security,则需要对其进行配置以

  • 禁用对控制台的请求的CSRF保护,

  • 在控制台的响应中设置头X-Frame-OptionsSAMEORIGIN

有关CSRF和头部X-Frame-Options的更多信息,请参阅Spring Security参考指南。

在简单的设置中,可以使用以下SecurityFilterChain

Java
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Profile("dev")
@Configuration(proxyBeanMethods = false)
public class DevProfileSecurityConfiguration {

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    SecurityFilterChain h2ConsoleSecurityFilterChain(HttpSecurity http) throws Exception {
        http.securityMatcher(PathRequest.toH2Console());
        http.authorizeHttpRequests(yourCustomAuthorization());
        http.csrf((csrf) -> csrf.disable());
        http.headers((headers) -> headers.frameOptions((frame) -> frame.sameOrigin()));
        return http.build();
    }


}
Kotlin
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Profile
import org.springframework.core.Ordered
import org.springframework.core.annotation.Order
import org.springframework.security.config.Customizer
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.web.SecurityFilterChain

@Profile("dev")
@Configuration(proxyBeanMethods = false)
class DevProfileSecurityConfiguration {

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    fun h2ConsoleSecurityFilterChain(http: HttpSecurity): SecurityFilterChain {
        return http.authorizeHttpRequests(yourCustomAuthorization())
            .csrf { csrf -> csrf.disable() }
            .headers { headers -> headers.frameOptions { frameOptions -> frameOptions.sameOrigin() } }
            .build()
    }


}
H2控制台仅用于开发过程中使用。在生产环境中,禁用CSRF保护或允许网站的框架可能会带来严重的安全风险。
PathRequest.toH2Console()在控制台路径已自定义时返回正确的请求匹配器。

1.7. 使用 jOOQ

jOOQ面向对象查询(jOOQ)是来自Data Geekery的热门产品,它可以从您的数据库生成Java代码,并通过其流畅的API构建类型安全的SQL查询。商业版和开源版均可与Spring Boot一起使用。

1.7.1. 代码生成

为了使用jOOQ的类型安全查询,您需要从数据库模式生成Java类。您可以按照jOOQ用户手册中的说明进行操作。如果您使用了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>

1.7.2. 使用 DSLContext

jOOQ提供的流畅API是通过org.jooq.DSLContext接口启动的。Spring Boot会自动将DSLContext配置为Spring Bean,并将其连接到您的应用程序DataSource。要使用DSLContext,您可以像以下示例中所示注入它:

Java
import java.util.GregorianCalendar;
import java.util.List;

import org.jooq.DSLContext;

import org.springframework.stereotype.Component;

import static org.springframework.boot.docs.data.sql.jooq.dslcontext.Tables.AUTHOR;

@Component
public class MyBean {

    private final DSLContext create;

    public MyBean(DSLContext dslContext) {
        this.create = dslContext;
    }


}
Kotlin
import org.jooq.DSLContext
import org.springframework.stereotype.Component
import java.util.GregorianCalendar

@Component
class MyBean(private val create: DSLContext) {


}
jOOQ手册通常使用名为create的变量来保存DSLContext

然后,您可以使用DSLContext构建您的查询,如以下示例所示:

Java
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);
Kotlin
fun authorsBornAfter1980(): List<GregorianCalendar> {
    return create.selectFrom<Tables.TAuthorRecord>(Tables.AUTHOR)
        .where(Tables.AUTHOR?.DATE_OF_BIRTH?.greaterThan(GregorianCalendar(1980, 0, 1)))
        .fetch(Tables.AUTHOR?.DATE_OF_BIRTH)
}

1.7.3. jOOQ SQL 方言

除非已配置spring.jooq.sql-dialect属性,否则Spring Boot会确定要为您的数据源使用的SQL方言。如果Spring Boot无法检测到方言,则使用DEFAULT

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

1.7.4. 自定义 jOOQ

可以通过定义自己的DefaultConfigurationCustomizer bean来实现更高级的定制,该bean将在创建org.jooq.Configuration @Bean之前调用。这比自动配置应用的任何内容都具有优先级。

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

1.8. 使用 R2DBC

响应式关系数据库连接(R2DBC)项目将响应式编程API引入关系数据库。R2DBC的 io.r2dbc.spi.Connection 提供了一种标准的非阻塞数据库连接工作方法。连接是通过使用类似于jdbc的 ConnectionFactory 提供的。

ConnectionFactory 的配置由 spring.r2dbc.* 中的外部配置属性控制。例如,您可以在 application.properties 中声明以下部分:

属性
spring.r2dbc.url=r2dbc:postgresql://localhost/test
spring.r2dbc.username=dbuser
spring.r2dbc.password=dbpass
Yaml
spring:
  r2dbc:
    url: "r2dbc:postgresql://localhost/test"
    username: "dbuser"
    password: "dbpass"
您无需指定驱动程序类名,因为Spring Boot会从R2DBC的连接工厂发现中获取驱动程序。
至少应提供url。在URL中指定的信息优先于单独的属性,即 nameusernamepassword 和池选项。
“如何”部分包括有关如何初始化数据库的部分

要自定义由 ConnectionFactory 创建的连接,即设置一些您不希望(或无法)在中央数据库配置中配置的特定参数,您可以使用 ConnectionFactoryOptionsBuilderCustomizer @Bean。以下示例展示了如何手动覆盖数据库端口,而其余选项取自应用程序配置:

Java
import io.r2dbc.spi.ConnectionFactoryOptions;

import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyR2dbcConfiguration {

    @Bean
    public ConnectionFactoryOptionsBuilderCustomizer connectionFactoryPortCustomizer() {
        return (builder) -> builder.option(ConnectionFactoryOptions.PORT, 5432);
    }

}
Kotlin
import io.r2dbc.spi.ConnectionFactoryOptions
import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyR2dbcConfiguration {

    @Bean
    fun connectionFactoryPortCustomizer(): ConnectionFactoryOptionsBuilderCustomizer {
        return ConnectionFactoryOptionsBuilderCustomizer { builder ->
            builder.option(ConnectionFactoryOptions.PORT, 5432)
        }
    }

}

以下示例展示了如何设置一些PostgreSQL连接选项:

Java
import java.util.HashMap;
import java.util.Map;

import io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider;

import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyPostgresR2dbcConfiguration {

    @Bean
    public ConnectionFactoryOptionsBuilderCustomizer postgresCustomizer() {
        Map<String, String> options = new HashMap<>();
        options.put("lock_timeout", "30s");
        options.put("statement_timeout", "60s");
        return (builder) -> builder.option(PostgresqlConnectionFactoryProvider.OPTIONS, options);
    }

}
Kotlin
import io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider
import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyPostgresR2dbcConfiguration {

    @Bean
    fun postgresCustomizer(): ConnectionFactoryOptionsBuilderCustomizer {
        val options: MutableMap<String, String> = HashMap()
        options["lock_timeout"] = "30s"
        options["statement_timeout"] = "60s"
        return ConnectionFactoryOptionsBuilderCustomizer { builder ->
            builder.option(PostgresqlConnectionFactoryProvider.OPTIONS, options)
        }
    }

}

当存在 ConnectionFactory bean 时,常规的JDBC DataSource 自动配置会被禁用。如果要保留JDBC DataSource 自动配置,并且愿意在响应式应用程序中使用阻塞的JDBC API 的风险,可以在应用程序中的 @Configuration 类上添加 @Import(DataSourceAutoConfiguration.class) 以重新启用它。

1.8.1. 嵌入式数据库支持

类似于JDBC支持,Spring Boot可以自动配置用于响应式使用的嵌入式数据库。您无需提供任何连接URL。您只需包含要使用的嵌入式数据库的构建依赖项,如以下示例所示:

<dependency>
    <groupId>io.r2dbc</groupId>
    <artifactId>r2dbc-h2</artifactId>
    <scope>runtime</scope>
</dependency>

如果您在测试中使用此功能,您可能会注意到整个测试套件重用相同的数据库,而不管您使用的应用程序上下文数量如何。如果要确保每个上下文都有一个单独的嵌入式数据库,应将 spring.r2dbc.generate-unique-name 设置为 true

1.8.2. 使用 DatabaseClient

DatabaseClient bean 被自动配置,您可以直接将其 @Autowire 到您自己的bean中,如以下示例所示:

Java
import java.util.Map;

import reactor.core.publisher.Flux;

import org.springframework.r2dbc.core.DatabaseClient;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final DatabaseClient databaseClient;

    public MyBean(DatabaseClient databaseClient) {
        this.databaseClient = databaseClient;
    }

    // ...

    public Flux<Map<String, Object>> someMethod() {
        return this.databaseClient.sql("select * from user").fetch().all();
    }

}
Kotlin
import org.springframework.r2dbc.core.DatabaseClient
import org.springframework.stereotype.Component
import reactor.core.publisher.Flux

@Component
class MyBean(private val databaseClient: DatabaseClient) {

    // ...

    fun someMethod(): Flux<Map<String, Any>> {
        return databaseClient.sql("select * from user").fetch().all()
    }

}

1.8.3. Spring Data R2DBC 仓库

Spring Data R2DBC 仓库是您可以定义的用于访问数据的接口。查询会根据您的方法名称自动生成。例如,一个 CityRepository 接口可能声明一个 findAllByState(String state) 方法来查找给定州内的所有城市。

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

Spring Data 仓库通常扩展自 RepositoryCrudRepository 接口。如果使用自动配置,将搜索自动配置包以查找仓库。

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

Java
import reactor.core.publisher.Mono;

import org.springframework.data.repository.Repository;

public interface CityRepository extends Repository<City, Long> {

    Mono<City> findByNameAndStateAllIgnoringCase(String name, String state);

}
Kotlin
import org.springframework.data.repository.Repository
import reactor.core.publisher.Mono

interface CityRepository : Repository<City?, Long?> {

    fun findByNameAndStateAllIgnoringCase(name: String?, state: String?): Mono<City?>?

}
我们仅仅触及了 Spring Data R2DBC 的表面。有关完整详情,请参阅 Spring Data R2DBC 参考文档

2. 使用NoSQL技术

Spring Data提供了额外的项目,帮助您访问各种NoSQL技术,包括:

其中,Spring Boot为Cassandra、Couchbase、Elasticsearch、LDAP、MongoDB、Neo4J和Redis提供了自动配置。此外,Spring Boot for Apache Geode提供了Apache Geode的自动配置。您可以使用其他项目,但必须自行配置。请参阅spring.io/projects/spring-data上的相应参考文档。

Spring Boot还为InfluxDB客户端提供了自动配置,但已弃用,推荐使用新的InfluxDB Java客户端,该客户端提供了自己的Spring Boot集成。

2.1. Redis

Redis是一个缓存、消息代理和功能丰富的键值存储。Spring Boot为LettuceJedis客户端库以及Spring Data Redis提供了基本的自动配置。

有一个“Starter”spring-boot-starter-data-redis,可以方便地收集依赖关系。默认情况下,它使用Lettuce。该“Starter”处理传统和响应式应用程序。

我们还提供了一个“Starter”spring-boot-starter-data-redis-reactive,以保持与其他支持响应式的存储一致。

2.1.1. 连接到Redis

您可以像使用其他Spring Bean一样注入自动配置的RedisConnectionFactoryStringRedisTemplate或普通的RedisTemplate实例。以下示例显示了这样一个Bean的示例:

Java
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final StringRedisTemplate template;

    public MyBean(StringRedisTemplate template) {
        this.template = template;
    }

    // ...

    public Boolean someMethod() {
        return this.template.hasKey("spring");
    }

}
Kotlin
import org.springframework.data.redis.core.StringRedisTemplate
import org.springframework.stereotype.Component

@Component
class MyBean(private val template: StringRedisTemplate) {

    // ...

    fun someMethod(): Boolean {
        return template.hasKey("spring")
    }

}

默认情况下,该实例尝试连接到localhost:6379上的Redis服务器。您可以使用spring.data.redis.*属性指定自定义连接详细信息,如下例所示:

属性
spring.data.redis.host=localhost
spring.data.redis.port=6379
spring.data.redis.database=0
spring.data.redis.username=user
spring.data.redis.password=secret
Yaml
spring:
  data:
    redis:
      host: "localhost"
      port: 6379
      database: 0
      username: "user"
      password: "secret"
您还可以注册任意数量实现LettuceClientConfigurationBuilderCustomizer的Bean进行更高级的自定义。也可以使用ClientResourcesBuilderCustomizer自定义ClientResources。如果使用Jedis,还可以使用JedisClientConfigurationBuilderCustomizer。或者,您可以注册类型为RedisStandaloneConfigurationRedisSentinelConfigurationRedisClusterConfiguration的Bean,以完全控制配置。

如果添加自己的任何自动配置类型的@Bean,它将替换默认值(除了在RedisTemplate的情况下,排除是基于Bean名称redisTemplate,而不是其类型)。

默认情况下,如果类路径上存在commons-pool2,将自动配置池化连接工厂。

自动配置的RedisConnectionFactory可以配置为使用SSL与服务器通信,设置如下示例中的属性:

属性
spring.data.redis.ssl.enabled=true
Yaml
spring:
  data:
    redis:
      ssl:
        enabled: true

可以在SSL包中配置自定义SSL信任材料,并将其应用于RedisConnectionFactory,如下例所示:

属性
spring.data.redis.ssl.bundle=example
Yaml
spring:
  data:
    redis:
      ssl:
        bundle: "example"

2.2. MongoDB

MongoDB是一种开源的NoSQL文档数据库,它使用类似JSON的模式而不是传统基于表的关系数据。Spring Boot提供了许多便利的功能来与MongoDB一起工作,包括spring-boot-starter-data-mongodbspring-boot-starter-data-mongodb-reactive“Starters”。

2.2.1. 连接到MongoDB数据库

要访问MongoDB数据库,您可以注入一个自动配置的org.springframework.data.mongodb.MongoDatabaseFactory。默认情况下,该实例尝试连接到mongodb://localhost/test上的MongoDB服务器。以下示例显示了如何连接到MongoDB数据库:

Java
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;

import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final MongoDatabaseFactory mongo;

    public MyBean(MongoDatabaseFactory mongo) {
        this.mongo = mongo;
    }

    // ...

    public MongoCollection<Document> someMethod() {
        MongoDatabase db = this.mongo.getMongoDatabase();
        return db.getCollection("users");
    }

}
Kotlin
import com.mongodb.client.MongoCollection
import org.bson.Document
import org.springframework.data.mongodb.MongoDatabaseFactory
import org.springframework.stereotype.Component

@Component
class MyBean(private val mongo: MongoDatabaseFactory) {

    // ...

    fun someMethod(): MongoCollection<Document> {
        val db = mongo.mongoDatabase
        return db.getCollection("users")
    }

}

如果您已经定义了自己的MongoClient,它将用于自动配置一个合适的MongoDatabaseFactory

自动配置的MongoClient是使用MongoClientSettings bean创建的。如果您已经定义了自己的MongoClientSettings,它将被使用而不会被修改,并且spring.data.mongodb属性将被忽略。否则,将自动配置一个MongoClientSettings,并将spring.data.mongodb属性应用于它。在任何情况下,您都可以声明一个或多个MongoClientSettingsBuilderCustomizer bean来微调MongoClientSettings配置。每个都将按顺序调用,使用MongoClientSettings.Builder来构建MongoClientSettings

您可以设置spring.data.mongodb.uri属性来更改URL并配置其他设置,例如副本集,如下例所示:

属性
spring.data.mongodb.uri=mongodb://user:[email protected]:27017,mongoserver2.example.com:23456/test
Yaml
spring:
  data:
    mongodb:
      uri: "mongodb://user:[email protected]:27017,mongoserver2.example.com:23456/test"

或者,您可以使用离散属性来指定连接详细信息。例如,您可以在您的application.properties中声明以下设置:

属性
spring.data.mongodb.host=mongoserver1.example.com
spring.data.mongodb.port=27017
spring.data.mongodb.additional-hosts[0]=mongoserver2.example.com:23456
spring.data.mongodb.database=test
spring.data.mongodb.username=user
spring.data.mongodb.password=secret
Yaml
spring:
  data:
    mongodb:
      host: "mongoserver1.example.com"
      port: 27017
      additional-hosts:
      - "mongoserver2.example.com:23456"
      database: "test"
      username: "user"
      password: "secret"

自动配置的MongoClient可以配置为使用SSL与服务器进行通信,方法是设置如下示例中所示的属性:

属性
spring.data.mongodb.uri=mongodb://user:[email protected]:27017,mongoserver2.example.com:23456/test
spring.data.mongodb.ssl.enabled=true
Yaml
spring:
  data:
    mongodb:
      uri: "mongodb://user:[email protected]:27017,mongoserver2.example.com:23456/test"
      ssl:
        enabled: true

可以在SSL bundle中配置自定义SSL信任材料,并将其应用于MongoClient,如下例所示:

属性
spring.data.mongodb.uri=mongodb://user:[email protected]:27017,mongoserver2.example.com:23456/test
spring.data.mongodb.ssl.bundle=example
Yaml
spring:
  data:
    mongodb:
      uri: "mongodb://user:[email protected]:27017,mongoserver2.example.com:23456/test"
      ssl:
        bundle: "example"

如果未指定spring.data.mongodb.port,则将使用默认值27017。您可以从前面示例中删除此行。

您还可以将端口作为主机地址的一部分来指定,使用host:port语法。如果需要更改additional-hosts条目的端口,则应使用此格式。

如果您不使用Spring Data MongoDB,可以注入一个MongoClient bean,而不是使用MongoDatabaseFactory。如果您想完全控制建立MongoDB连接,还可以声明自己的MongoDatabaseFactoryMongoClient bean。
如果使用响应式驱动程序,则需要Netty来进行SSL。如果Netty可用且尚未自定义要使用的工厂,则自动配置将自动配置此工厂。

2.2.2. MongoTemplate

Spring Data MongoDB提供了一个非常类似于Spring的JdbcTemplate设计的MongoTemplate类。与JdbcTemplate一样,Spring Boot会自动为您配置一个bean以便注入模板,如下所示:

Java
import com.mongodb.client.MongoCollection;
import org.bson.Document;

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final MongoTemplate mongoTemplate;

    public MyBean(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    // ...

    public MongoCollection<Document> someMethod() {
        return this.mongoTemplate.getCollection("users");
    }

}
Kotlin
import com.mongodb.client.MongoCollection
import org.bson.Document
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.stereotype.Component

@Component
class MyBean(private val mongoTemplate: MongoTemplate) {

    // ...

    fun someMethod(): MongoCollection<Document> {
        return mongoTemplate.getCollection("users")
    }

}

查看完整详情,请参阅MongoOperations Javadoc

2.2.3. Spring Data MongoDB Repositories

Spring Data为MongoDB提供了存储库支持。与之前讨论的JPA存储库一样,基本原则是根据方法名称自动构建查询。

事实上,Spring Data JPA和Spring Data MongoDB共享相同的基础架构。您可以使用之前的JPA示例,并假设City现在是一个MongoDB数据类而不是JPA的@Entity,它可以以相同的方式工作,如下例所示:

Java
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;

public interface CityRepository extends Repository<City, Long> {

    Page<City> findAll(Pageable pageable);

    City findByNameAndStateAllIgnoringCase(String name, String state);

}
Kotlin
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.repository.Repository

interface CityRepository :
    Repository<City?, Long?> {
    fun findAll(pageable: Pageable?): Page<City?>?
    fun findByNameAndStateAllIgnoringCase(name: String?, state: String?): City?
}

存储库和文档是通过扫描找到的。默认情况下,会扫描自动配置包。您可以通过使用@EnableMongoRepositories@EntityScan来自定义要查找存储库和文档的位置。

有关Spring Data MongoDB的完整详情,包括其丰富的对象映射技术,请参阅其参考文档

2.3. Neo4j

Neo4j是一种开源的NoSQL图形数据库,使用节点之间通过一级关系连接的丰富数据模型,比传统的关系型数据库管理系统更适合处理连接的大数据。Spring Boot为使用Neo4j提供了几种便利方式,包括spring-boot-starter-data-neo4j“Starter”。

2.3.1. 连接到Neo4j数据库

要访问Neo4j服务器,您可以注入一个自动配置的org.neo4j.driver.Driver。默认情况下,该实例尝试使用Bolt协议连接到位于localhost:7687的Neo4j服务器。以下示例显示了如何注入一个Neo4j Driver,让您可以访问Session等内容:

Java
import org.neo4j.driver.Driver;
import org.neo4j.driver.Session;
import org.neo4j.driver.Values;

import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final Driver driver;

    public MyBean(Driver driver) {
        this.driver = driver;
    }

    // ...

    public String someMethod(String message) {
        try (Session session = this.driver.session()) {
            return session.executeWrite(
                    (transaction) -> transaction
                        .run("CREATE (a:Greeting) SET a.message = $message RETURN a.message + ', from node ' + id(a)",
                                Values.parameters("message", message))
                        .single()
                        .get(0)
                        .asString());
        }
    }

}
Kotlin
import org.neo4j.driver.*
import org.springframework.stereotype.Component

@Component
class MyBean(private val driver: Driver) {

    // ...

    fun someMethod(message: String?): String {
        driver.session().use { session ->
            return@someMethod session.executeWrite { transaction: TransactionContext ->
                transaction
                    .run(
                        "CREATE (a:Greeting) SET a.message = \$message RETURN a.message + ', from node ' + id(a)",
                        Values.parameters("message", message)
                    )
                    .single()[0].asString()
            }
        }
    }

}

您可以使用spring.neo4j.*属性配置驱动程序的各个方面。以下示例显示了如何配置uri和凭据:

属性
spring.neo4j.uri=bolt://my-server:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=secret
Yaml
spring:
  neo4j:
    uri: "bolt://my-server:7687"
    authentication:
      username: "neo4j"
      password: "secret"

自动配置的Driver是使用ConfigBuilder创建的。要微调其配置,声明一个或多个ConfigBuilderCustomizer bean。每个bean将按顺序调用用于构建DriverConfigBuilder

2.3.2. Spring Data Neo4j Repositories

Spring Data包括对Neo4j的存储库支持。有关Spring Data Neo4j的完整详细信息,请参阅参考文档

Spring Data Neo4j与Spring Data JPA共享通用基础设施,就像许多其他Spring Data模块一样。您可以使用之前的JPA示例,并将City定义为Spring Data Neo4j的@Node,而不是JPA的@Entity,存储库抽象工作方式相同,如下例所示:

Java
import java.util.Optional;

import org.springframework.data.neo4j.repository.Neo4jRepository;

public interface CityRepository extends Neo4jRepository<City, Long> {

    Optional<City> findOneByNameAndState(String name, String state);

}
Kotlin
import org.springframework.data.neo4j.repository.Neo4jRepository
import java.util.Optional

interface CityRepository : Neo4jRepository<City?, Long?> {

    fun findOneByNameAndState(name: String?, state: String?): Optional<City?>?

}

spring-boot-starter-data-neo4j“Starter”不仅启用了存储库支持,还启用了事务管理。Spring Boot支持经典和响应式Neo4j存储库,使用Neo4jTemplateReactiveNeo4jTemplate bean。当类路径上可用Project Reactor时,还会自动配置响应式样式。

存储库和实体通过扫描找到。默认情况下,将扫描自动配置包。您可以通过使用@EnableNeo4jRepositories@EntityScan自定义要查找存储库和实体的位置。

在使用响应式样式的应用程序中,不会自动配置ReactiveTransactionManager。要启用事务管理,必须在您的配置中定义以下bean:

Java
import org.neo4j.driver.Driver;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.core.ReactiveDatabaseSelectionProvider;
import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager;

@Configuration(proxyBeanMethods = false)
public class MyNeo4jConfiguration {

    @Bean
    public ReactiveNeo4jTransactionManager reactiveTransactionManager(Driver driver,
            ReactiveDatabaseSelectionProvider databaseNameProvider) {
        return new ReactiveNeo4jTransactionManager(driver, databaseNameProvider);
    }

}
Kotlin
import org.neo4j.driver.Driver
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.neo4j.core.ReactiveDatabaseSelectionProvider
import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager

@Configuration(proxyBeanMethods = false)
class MyNeo4jConfiguration {

    @Bean
    fun reactiveTransactionManager(driver: Driver,
            databaseNameProvider: ReactiveDatabaseSelectionProvider): ReactiveNeo4jTransactionManager {
        return ReactiveNeo4jTransactionManager(driver, databaseNameProvider)
    }
}

2.4. Elasticsearch

Elasticsearch是一个开源的、分布式的、RESTful的搜索和分析引擎。Spring Boot为Elasticsearch客户端提供了基本的自动配置。

Spring Boot支持多个客户端:

  • 官方低级别REST客户端

  • 官方Java API客户端

  • 由Spring Data Elasticsearch提供的ReactiveElasticsearchClient

Spring Boot提供了一个专用的“Starter”,spring-boot-starter-data-elasticsearch

2.4.1. 使用REST客户端连接到Elasticsearch

Elasticsearch提供了两种不同的REST客户端,您可以使用它们来查询集群:来自org.elasticsearch.client:elasticsearch-rest-client模块的低级别客户端和来自co.elastic.clients:elasticsearch-java模块的Java API客户端。此外,Spring Boot还提供了对来自org.springframework.data:spring-data-elasticsearch模块的响应式客户端的支持。默认情况下,客户端将目标定位为localhost:9200。您可以使用spring.elasticsearch.*属性进一步调整客户端的配置,如下例所示:

属性
spring.elasticsearch.uris=https://search.example.com:9200
spring.elasticsearch.socket-timeout=10s
spring.elasticsearch.username=user
spring.elasticsearch.password=secret
Yaml
spring:
  elasticsearch:
    uris: "https://search.example.com:9200"
    socket-timeout: "10s"
    username: "user"
    password: "secret"
使用RestClient连接到Elasticsearch

如果类路径中有elasticsearch-rest-client,Spring Boot将自动配置并注册一个RestClient bean。除了前面描述的属性外,为了微调RestClient,您可以注册任意数量实现RestClientBuilderCustomizer的bean以进行更高级的自定义。要完全控制客户端的配置,定义一个RestClientBuilder bean。

此外,如果类路径中有elasticsearch-rest-client-sniffer,将自动配置一个Sniffer以自动发现运行中的Elasticsearch集群中的节点,并将它们设置在RestClient bean上。您可以进一步调整Sniffer的配置,如下例所示:

属性
spring.elasticsearch.restclient.sniffer.interval=10m
spring.elasticsearch.restclient.sniffer.delay-after-failure=30s
Yaml
spring:
  elasticsearch:
    restclient:
      sniffer:
        interval: "10m"
        delay-after-failure: "30s"
使用ElasticsearchClient连接到Elasticsearch

如果类路径中有co.elastic.clients:elasticsearch-java,Spring Boot将自动配置并注册一个ElasticsearchClient bean。

ElasticsearchClient使用一个取决于前面描述的RestClient的传输。因此,前面描述的属性可用于配置ElasticsearchClient。此外,您可以定义一个RestClientOptions bean来进一步控制传输的行为。

使用ReactiveElasticsearchClient连接到Elasticsearch

Spring Data Elasticsearch提供了ReactiveElasticsearchClient,用于以响应式方式查询Elasticsearch实例。如果类路径中有Spring Data Elasticsearch和Reactor,Spring Boot将自动配置并注册一个ReactiveElasticsearchClient

ReactiveElasticsearchClient使用一个取决于前面描述的RestClient的传输。因此,前面描述的属性可用于配置ReactiveElasticsearchClient。此外,您可以定义一个RestClientOptions bean来进一步控制传输的行为。

2.4.2. 使用Spring Data连接到Elasticsearch

要连接到Elasticsearch,必须定义一个ElasticsearchClient bean,由Spring Boot自动配置或应用程序手动提供(请参阅前面的部分)。配置完成后,可以像注入其他Spring bean一样注入一个ElasticsearchTemplate,如下例所示:

Java
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final ElasticsearchTemplate template;

    public MyBean(ElasticsearchTemplate template) {
        this.template = template;
    }

    // ...

    public boolean someMethod(String id) {
        return this.template.exists(id, User.class);
    }

}
Kotlin
import org.springframework.stereotype.Component

@Component
class MyBean(private val template: org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate ) {

    // ...

    fun someMethod(id: String): Boolean {
        return template.exists(id, User::class.java)
    }

}

在有spring-data-elasticsearch和Reactor的情况下,Spring Boot还可以自动配置一个ReactiveElasticsearchClient和一个ReactiveElasticsearchTemplate作为bean。它们是其他REST客户端的响应式等价物。

2.4.3. Spring Data Elasticsearch 仓库

Spring Data 包含对 Elasticsearch 的仓库支持。与之前讨论的 JPA 仓库一样,基本原则是根据方法名称自动为您构建查询。

事实上,Spring Data JPA 和 Spring Data Elasticsearch 共享相同的基础架构。您可以使用之前的 JPA 示例,并假设 City 现在是一个 Elasticsearch 的 @Document 类,而不是 JPA 的 @Entity,它的工作方式是相同的。

仓库和文档是通过扫描找到的。默认情况下,会扫描自动配置包。您可以通过分别使用 @EnableElasticsearchRepositories@EntityScan 来自定义查找仓库和文档的位置。

有关 Spring Data Elasticsearch 的完整详情,请参阅参考文档

Spring Boot 支持经典和响应式 Elasticsearch 仓库,使用 ElasticsearchRestTemplateReactiveElasticsearchTemplate bean。在必要的依赖项存在的情况下,Spring Boot 很可能会自动配置这些 bean。

如果您希望使用自己的模板来支持 Elasticsearch 仓库,可以添加自己的 ElasticsearchRestTemplateElasticsearchOperations @Bean,只要它的名称为 "elasticsearchTemplate"。对于 ReactiveElasticsearchTemplateReactiveElasticsearchOperations,也适用相同的规则,bean 名称为 "reactiveElasticsearchTemplate"

您可以选择通过以下属性禁用仓库支持:

属性
spring.data.elasticsearch.repositories.enabled=false
Yaml
spring:
  data:
    elasticsearch:
      repositories:
        enabled: false

2.5. Cassandra

Cassandra 是一个开源的、分布式的数据库管理系统,旨在处理大量数据跨多台普通服务器。Spring Boot为Cassandra提供了自动配置,并提供了由Spring Data Cassandra提供的抽象层。有一个“Starter”spring-boot-starter-data-cassandra用于方便地收集依赖项。

2.5.1. 连接到Cassandra

您可以像处理其他Spring Bean一样注入一个自动配置的CassandraTemplate或Cassandra CqlSession实例。可以使用spring.cassandra.*属性来自定义连接。通常,您提供keyspace-namecontact-points以及本地数据中心名称,如下例所示:

属性
spring.cassandra.keyspace-name=mykeyspace
spring.cassandra.contact-points=cassandrahost1:9042,cassandrahost2:9042
spring.cassandra.local-datacenter=datacenter1
Yaml
spring:
  cassandra:
    keyspace-name: "mykeyspace"
    contact-points: "cassandrahost1:9042,cassandrahost2:9042"
    local-datacenter: "datacenter1"

如果所有联系点的端口相同,您可以使用快捷方式仅指定主机名,如下例所示:

属性
spring.cassandra.keyspace-name=mykeyspace
spring.cassandra.contact-points=cassandrahost1,cassandrahost2
spring.cassandra.local-datacenter=datacenter1
Yaml
spring:
  cassandra:
    keyspace-name: "mykeyspace"
    contact-points: "cassandrahost1,cassandrahost2"
    local-datacenter: "datacenter1"
这两个示例是相同的,因为端口默认为9042。如果需要配置端口,请使用spring.cassandra.port

自动配置的CqlSession可以通过设置以下示例中显示的属性来配置使用SSL与服务器进行通信:

属性
spring.cassandra.keyspace-name=mykeyspace
spring.cassandra.contact-points=cassandrahost1,cassandrahost2
spring.cassandra.local-datacenter=datacenter1
spring.cassandra.ssl.enabled=true
Yaml
spring:
  cassandra:
    keyspace-name: "mykeyspace"
    contact-points: "cassandrahost1,cassandrahost2"
    local-datacenter: "datacenter1"
    ssl:
      enabled: true

可以在SSL包中配置自定义SSL信任材料,并将其应用于CqlSession,如下例所示:

属性
spring.cassandra.keyspace-name=mykeyspace
spring.cassandra.contact-points=cassandrahost1,cassandrahost2
spring.cassandra.local-datacenter=datacenter1
spring.cassandra.ssl.bundle=example
Yaml
spring:
  cassandra:
    keyspace-name: "mykeyspace"
    contact-points: "cassandrahost1,cassandrahost2"
    local-datacenter: "datacenter1"
    ssl:
      bundle: "example"

Cassandra驱动程序有自己的配置基础架构,在类路径的根目录加载application.conf

Spring Boot默认不会查找这样的文件,但可以使用spring.cassandra.config加载一个。如果属性同时存在于spring.cassandra.*和配置文件中,则spring.cassandra.*中的值优先。

对于更高级的驱动程序定制,您可以注册任意数量实现DriverConfigLoaderBuilderCustomizer的bean。可以使用CqlSessionBuilderCustomizer类型的bean自定义CqlSession

如果使用CqlSessionBuilder创建多个CqlSession bean,请记住构建器是可变的,因此确保为每个会话注入一个新的副本。

以下代码清单显示了如何注入一个Cassandra bean:

Java
import org.springframework.data.cassandra.core.CassandraTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final CassandraTemplate template;

    public MyBean(CassandraTemplate template) {
        this.template = template;
    }

    // ...

    public long someMethod() {
        return this.template.count(User.class);
    }

}
Kotlin
import org.springframework.data.cassandra.core.CassandraTemplate
import org.springframework.stereotype.Component

@Component
class MyBean(private val template: CassandraTemplate) {

    // ...

    fun someMethod(): Long {
        return template.count(User::class.java)
    }

}

如果添加自己的@Bean类型为CassandraTemplate,它将替换默认值。

2.5.2. Spring Data Cassandra Repositories

Spring Data包括对Cassandra的基本存储库支持。目前,这比之前讨论的JPA存储库更有限,并且需要使用@Query注释的查找器方法。

存储库和实体通过扫描找到。默认情况下,将扫描自动配置包。您可以通过分别使用@EnableCassandraRepositories@EntityScan来自定义要查找存储库和实体的位置。

有关Spring Data Cassandra的完整详情,请参阅参考文档

2.6. Couchbase

Couchbase是一个面向交互式应用程序优化的开源、分布式、多模型NoSQL文档数据库。Spring Boot为Couchbase提供了自动配置,并提供了由Spring Data Couchbase提供的抽象层。有spring-boot-starter-data-couchbasespring-boot-starter-data-couchbase-reactive“Starters”可方便地收集依赖项。

2.6.1. 连接到Couchbase

您可以通过添加Couchbase SDK和一些配置来获取一个Cluster。可以使用spring.couchbase.*属性来自定义连接。通常,您提供连接字符串、用户名和密码,如下例所示:

属性
spring.couchbase.connection-string=couchbase://192.168.1.123
spring.couchbase.username=user
spring.couchbase.password=secret
Yaml
spring:
  couchbase:
    connection-string: "couchbase://192.168.1.123"
    username: "user"
    password: "secret"

您还可以自定义一些ClusterEnvironment设置。例如,以下配置更改了打开新Bucket的超时时间,并通过引用配置的SSL包启用SSL支持:

属性
spring.couchbase.env.timeouts.connect=3s
spring.couchbase.env.ssl.bundle=example
Yaml
spring:
  couchbase:
    env:
      timeouts:
        connect: "3s"
      ssl:
        bundle: "example"
查看更多有关spring.couchbase.env.*属性的详细信息。要更多控制,可以使用一个或多个ClusterEnvironmentBuilderCustomizer bean。

2.6.2. Spring Data Couchbase Repositories

Spring Data包括对Couchbase的存储库支持。

通过扫描可以找到存储库和文档。默认情况下,会扫描自动配置包。您可以通过使用@EnableCouchbaseRepositories@EntityScan来自定义要查找存储库和文档的位置。

有关Spring Data Couchbase的完整详情,请参阅参考文档

您可以像使用任何其他Spring Bean一样注入一个自动配置的CouchbaseTemplate实例,前提是有一个CouchbaseClientFactory bean可用。当有一个可用的Cluster(如上所述)并且已指定桶名称时,就会发生这种情况:

属性
spring.data.couchbase.bucket-name=my-bucket
Yaml
spring:
  data:
    couchbase:
      bucket-name: "my-bucket"

以下示例显示了如何注入CouchbaseTemplate bean:

Java
import org.springframework.data.couchbase.core.CouchbaseTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final CouchbaseTemplate template;

    public MyBean(CouchbaseTemplate template) {
        this.template = template;
    }

    // ...

    public String someMethod() {
        return this.template.getBucketName();
    }

}
Kotlin
import org.springframework.data.couchbase.core.CouchbaseTemplate
import org.springframework.stereotype.Component

@Component
class MyBean(private val template: CouchbaseTemplate) {

    // ...

    fun someMethod(): String {
        return template.bucketName
    }

}

您可以在自己的配置中定义一些bean,以覆盖自动配置提供的bean:

  • 一个名称为couchbaseMappingContextCouchbaseMappingContext @Bean

  • 一个名称为couchbaseCustomConversionsCustomConversions @Bean

  • 一个名称为couchbaseTemplateCouchbaseTemplate @Bean

为了避免在自己的配置中硬编码这些名称,您可以重用Spring Data Couchbase提供的BeanNames。例如,您可以自定义要使用的转换器,如下所示:

Java
import org.assertj.core.util.Arrays;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.couchbase.config.BeanNames;
import org.springframework.data.couchbase.core.convert.CouchbaseCustomConversions;

@Configuration(proxyBeanMethods = false)
public class MyCouchbaseConfiguration {

    @Bean(BeanNames.COUCHBASE_CUSTOM_CONVERSIONS)
    public CouchbaseCustomConversions myCustomConversions() {
        return new CouchbaseCustomConversions(Arrays.asList(new MyConverter()));
    }

}
Kotlin
import org.assertj.core.util.Arrays
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.couchbase.config.BeanNames
import org.springframework.data.couchbase.core.convert.CouchbaseCustomConversions

@Configuration(proxyBeanMethods = false)
class MyCouchbaseConfiguration {

    @Bean(BeanNames.COUCHBASE_CUSTOM_CONVERSIONS)
    fun myCustomConversions(): CouchbaseCustomConversions {
        return CouchbaseCustomConversions(Arrays.asList(MyConverter()))
    }

}

2.7. LDAP

LDAP(轻量级目录访问协议)是一种开放的、供应商中立的、行业标准的应用协议,用于通过IP网络访问和维护分布式目录信息服务。Spring Boot提供了对任何符合LDAP服务器的自动配置,同时支持来自UnboundID的内存中嵌入式LDAP服务器。

LDAP抽象由Spring Data LDAP提供。有一个“Starter”spring-boot-starter-data-ldap用于方便地收集依赖项。

2.7.1. 连接到LDAP服务器

要连接到LDAP服务器,请确保在spring-boot-starter-data-ldap“Starter”或spring-ldap-core上声明依赖项,然后在应用程序属性中声明服务器的URL,如下例所示:

属性
spring.ldap.urls=ldap://myserver:1235
spring.ldap.username=admin
spring.ldap.password=secret
Yaml
spring:
  ldap:
    urls: "ldap://myserver:1235"
    username: "admin"
    password: "secret"

如果需要自定义连接设置,可以使用spring.ldap.basespring.ldap.base-environment属性。

基于这些设置,将自动配置一个LdapContextSource。如果有一个DirContextAuthenticationStrategy bean可用,它将与自动配置的LdapContextSource关联。如果需要自定义它,例如使用PooledContextSource,仍然可以注入自动配置的LdapContextSource。确保将您定制的ContextSource标记为@Primary,以便自动配置的LdapTemplate使用它。

2.7.2. Spring Data LDAP存储库

Spring Data包括对LDAP的存储库支持。

存储库和文档通过扫描找到。默认情况下,将扫描自动配置包。您可以通过使用@EnableLdapRepositories@EntityScan来自定义要查找存储库和文档的位置。

有关Spring Data LDAP的完整详细信息,请参阅参考文档

您还可以像处理其他Spring Bean一样注入一个自动配置的LdapTemplate实例,如下例所示:

Java
import java.util.List;

import org.springframework.ldap.core.LdapTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final LdapTemplate template;

    public MyBean(LdapTemplate template) {
        this.template = template;
    }

    // ...

    public List<User> someMethod() {
        return this.template.findAll(User.class);
    }

}
Kotlin
import org.springframework.ldap.core.LdapTemplate
import org.springframework.stereotype.Component

@Component
class MyBean(private val template: LdapTemplate) {

    // ...

    fun someMethod(): List<User> {
        return template.findAll(User::class.java)
    }

}

2.7.3. 内存中嵌入式LDAP服务器

为了测试目的,Spring Boot支持从UnboundID自动配置内存中嵌入式LDAP服务器。要配置服务器,请添加依赖项com.unboundid:unboundid-ldapsdk并声明一个spring.ldap.embedded.base-dn属性,如下所示:

属性
spring.ldap.embedded.base-dn=dc=spring,dc=io
Yaml
spring:
  ldap:
    embedded:
      base-dn: "dc=spring,dc=io"

可以定义多个base-dn值,但是由于区分名称通常包含逗号,因此必须使用正确的表示法进行定义。

在yaml文件中,您可以使用yaml列表表示法。在属性文件中,必须将索引包含在属性名称中:

属性
spring.ldap.embedded.base-dn[0]=dc=spring,dc=io
spring.ldap.embedded.base-dn[1]=dc=vmware,dc=com
Yaml
spring.ldap.embedded.base-dn:
  - "dc=spring,dc=io"
  - "dc=vmware,dc=com"

默认情况下,服务器在随机端口上启动并触发常规LDAP支持。不需要指定spring.ldap.urls属性。

如果在类路径上有一个schema.ldif文件,它将用于初始化服务器。如果要从不同资源加载初始化脚本,还可以使用spring.ldap.embedded.ldif属性。

默认情况下,使用标准模式来验证LDIF文件。您可以通过设置spring.ldap.embedded.validation.enabled属性来完全关闭验证。如果有自定义属性,可以使用spring.ldap.embedded.validation.schema来定义自定义属性类型或对象类。

2.8. InfluxDB

InfluxDB的自动配置已被弃用,并计划在Spring Boot 3.4中移除,以支持新的InfluxDB Java客户端,该客户端提供了自己的Spring Boot集成。

InfluxDB是一种为快速、高可用性存储和检索时间序列数据而优化的开源时间序列数据库,用于操作监控、应用程序指标、物联网传感器数据和实时分析等领域。

2.8.1. 连接到InfluxDB

Spring Boot会自动配置一个InfluxDB实例,前提是influxdb-java客户端在类路径上,并且使用spring.influx.url设置数据库的URL。

如果连接到InfluxDB需要用户和密码,可以相应地设置spring.influx.userspring.influx.password属性。

InfluxDB依赖于OkHttp。如果需要调整InfluxDB在后台使用的http客户端,可以注册一个InfluxDbOkHttpClientBuilderProvider bean。

如果需要更多对配置的控制,考虑注册一个InfluxDbCustomizer bean。

3. 接下来阅读什么

现在,您应该对如何将Spring Boot与各种数据技术一起使用有所了解。从这里开始,您可以阅读关于Spring Boot对各种消息传递技术的支持以及如何在您的应用程序中启用它们。