SQL データベース

Spring Framework は、JdbcClient (Javadoc) または JdbcTemplate (Javadoc) を使用した直接 JDBC アクセスから、Hibernate などの完全な「オブジェクトリレーショナルマッピング」テクノロジまで、SQL データベースを操作するための広範なサポートを提供します。Spring Data は、インターフェースから直接 Repository (Javadoc) 実装を作成し、規則を使用してメソッド名からクエリを生成するという、追加レベルの機能を提供します。

DataSource を構成する

Java の DataSource (標準 Javadoc) インターフェースは、データベース接続を操作するための標準的な方法を提供します。従来、DataSource (標準 Javadoc) は URL といくつかの資格情報を使用してデータベース接続を確立します。

より高度な例、通常は DataSource の構成を完全に制御する方法については、「使い方 ガイド」のカスタム DataSource を構成するセクションを参照してください。

組み込みデータベースのサポート

インメモリ埋め込みデータベースを使用してアプリケーションを開発すると便利な場合がよくあります。明らかに、インメモリデータベースは永続的なストレージを提供しません。アプリケーションの起動時にデータベースにデータを入力し、アプリケーションの終了時にデータを破棄する準備をする必要があります。

「使い方ガイド」セクションには、データベースを初期化する方法に関するセクションが含まれています。

Spring Boot は、組み込み H2 (英語) HSQL (英語) Derby [Apache] (英語) データベースを自動構成できます。接続 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 がデータベースを閉じるタイミングを制御できるため、データベースへのアクセスが不要になったときに確実に実行されます。

本番データベースへの接続

プーリング DataSource (標準 Javadoc) を使用して、本番データベース接続を自動構成することもできます。

DataSource の設定

DataSource 構成は、spring.datasource.*外部構成プロパティによって制御されます。例: application.properties で次のセクションを宣言できます。

  • プロパティ

  • YAML

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring:
  datasource:
    url: "jdbc:mysql://localhost/test"
    username: "dbuser"
    password: "dbpass"
spring.datasource.url プロパティを設定して、少なくとも URL を指定する必要があります。そうでない場合、Spring Boot は組み込みデータベースの自動構成を試みます。
Spring Boot は、ほとんどのデータベースの JDBC ドライバークラスを URL から推測できます。特定のクラスを指定する必要がある場合は、spring.datasource.driver-class-name プロパティを使用できます。
プーリング DataSource (標準 Javadoc) を作成するには、有効な Driver (標準 Javadoc) クラスが利用可能であることを確認できる必要があるため、何かを行う前にそのことを確認します。つまり、spring.datasource.driver-class-name=com.mysql.jdbc.Driver を設定する場合、そのクラスはロード可能である必要があります。

サポートされているオプションの詳細については、DataSourceProperties (Javadoc) API ドキュメントを参照してください。これらは、実際の実装に関係なく機能する標準オプションです。それぞれのプレフィックス (spring.datasource.hikari.*spring.datasource.tomcat.*spring.datasource.dbcp2.*spring.datasource.oracleucp.*) を使用して、実装固有の設定を微調整することもできます。詳細については、使用している接続プールの実装のドキュメントを参照してください。

たとえば、Tomcat 接続プール [Apache] (英語) を使用する場合、次の例に示すように、多くの追加設定をカスタマイズできます。

  • プロパティ

  • YAML

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

これにより、使用可能な接続がない場合に例外をスローする前に 10000 ミリ秒待機するようにプールが設定され、接続の最大数が 50 に制限され、プールから借用する前に接続が検証されます。

サポートされている接続プール

Spring Boot は、特定の実装を選択するために次のアルゴリズムを使用します。

  1. パフォーマンスと同時実行性の点から、HikariCP [GitHub] (英語) をお勧めします。HikariCP が使用可能な場合、常に選択します。

  2. それ以外の場合、Tomcat プーリング DataSource (標準 Javadoc) が利用可能な場合は、それを使用します。

  3. それ以外の場合、Commons DBCP2 [Apache] (英語) が利用可能な場合は、それを使用します。

  4. HikariCP、Tomcat、DBCP2 のいずれも使用できない場合、Oracle UCP が使用可能な場合は、それを使用します。

spring-boot-starter-jdbc または spring-boot-starter-data-jpa スターターを使用すると、自動的に HikariCP への依存関係が発生します。

spring.datasource.type プロパティを設定することにより、そのアルゴリズムを完全にバイパスし、使用する接続プールを指定できます。tomcat-jdbc はデフォルトで提供されているため、これは Tomcat コンテナーでアプリケーションを実行する場合に特に重要です。

追加の接続プールは、DataSourceBuilder (Javadoc) を使用していつでも手動で構成できます。独自の DataSource (標準 Javadoc) Bean を定義すると、自動構成は行われません。DataSourceBuilder (Javadoc) では次の接続プールがサポートされています。

JNDI DataSource への接続

Spring Boot アプリケーションをアプリケーションサーバーにデプロイする場合、アプリケーションサーバーの組み込み機能を使用して DataSource を構成および管理し、JNDI を使用してそれにアクセスすることができます。

spring.datasource.jndi-name プロパティは、特定の JNDI ロケーションから DataSource (標準 Javadoc) にアクセスするための spring.datasource.urlspring.datasource.usernamespring.datasource.password プロパティの代替として使用できます。例: application.properties の次のセクションは、JBoss AS で定義された DataSource (標準 Javadoc) にアクセスする方法を示しています。

  • プロパティ

  • YAML

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

JdbcTemplate の使用

Spring の JdbcTemplate (Javadoc) クラスと NamedParameterJdbcTemplate (Javadoc) クラスは自動構成されており、次の例に示すように、独自の Bean に直接自動接続できます。

  • Java

  • Kotlin

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 ...
	}

}
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.* プロパティを使用して、テンプレートの一部のプロパティをカスタマイズできます。

  • プロパティ

  • YAML

spring.jdbc.template.max-rows=500
spring:
  jdbc:
    template:
      max-rows: 500
NamedParameterJdbcTemplate (Javadoc) は、バックグラウンドで同じ JdbcTemplate (Javadoc) インスタンスを再利用します。複数の JdbcTemplate (Javadoc) が定義されていて、プライマリ候補が存在しない場合、NamedParameterJdbcTemplate (Javadoc) は自動構成されません。

JdbcClient の使用

Spring の JdbcClient (Javadoc) は、NamedParameterJdbcTemplate (Javadoc) の存在に基づいて自動的に構成されます。次の例に示すように、独自の Bean に直接注入することもできます。

  • Java

  • Kotlin

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 ...
	}

}
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 (Javadoc) を作成する場合、spring.jdbc.template.* プロパティを使用したカスタマイズもクライアントで考慮されます。

JPA および Spring Data JPA

Java Persistence API は、オブジェクトをリレーショナルデータベースに「マップ」できる標準テクノロジーです。spring-boot-starter-data-jpa POM を使用すると、簡単に開始できます。以下の重要な依存関係を提供します。

  • Hibernate: 最も一般的な JPA 実装の 1 つ。

  • Spring Data JPA: JPA ベースのリポジトリの実装に役立ちます。

  • Spring ORM: Spring Framework からのコア ORM サポート。

ここでは、JPA または Spring Data の詳細については詳しく説明しません。spring.ioJPA でデータアクセスガイドに従い、Spring Data JPA および Hibernate (英語) のリファレンスドキュメントを読むことができます。

エンティティクラス

従来、JPA「エンティティ」クラスは persistence.xml ファイルで指定されていました。Spring Boot では、このファイルは必要なく、代わりに "Entity Scanning" が使用されます。デフォルトでは、自動構成パッケージがスキャンされます。

@Entity (英語) @Embeddable (英語) 、または @MappedSuperclass (英語) でアノテーションが付けられたクラスが考慮されます。一般的なエンティティクラスは次の例のようになります。

  • Java

  • Kotlin

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;

	// ... additional members, often include @OneToMany mappings

	protected City() {
		// no-args constructor required by JPA spec
		// this one is protected since it should not 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

}
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

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

	// ... additional members, often include @OneToMany mappings

	protected constructor() {
		// no-args constructor required by JPA spec
		// this one is protected since it should not be used directly
	}

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

}
@EntityScan (Javadoc) アノテーションを使用して、エンティティのスキャン場所をカスタマイズできます。「使い方 ガイド」の Spring 構成から @Entity 定義を分離するセクションを参照してください。

Spring Data JPA リポジトリ

Spring Data JPA リポジトリは、データにアクセスするために定義できるインターフェースです。JPA クエリは、メソッド名から自動的に作成されます。例: CityRepository インターフェースは、特定の状態のすべての都市を見つけるために findAllByState(String state) メソッドを宣言する場合があります。

より複雑なクエリの場合、Spring Data の Query (Javadoc) アノテーションでメソッドにアノテーションを付けることができます。

Spring Data リポジトリは通常、Repository (Javadoc) または CrudRepository (Javadoc) インターフェースから拡張されます。自動構成を使用する場合、自動構成パッケージでリポジトリが検索されます。

@EnableJpaRepositories (Javadoc) を使用してリポジトリを検索する場所をカスタマイズできます。

次の例は、典型的な Spring Data リポジトリインターフェース定義を示しています。

  • Java

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

public interface CityRepository extends Repository<City, Long> {

	Page<City> findAll(Pageable pageable);

	City findByNameAndStateAllIgnoringCase(String name, String state);

}
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 リポジトリは、デフォルト、遅延、遅延の 3 つの異なるブートストラップモードをサポートしています。遅延または遅延ブートストラップを有効にするには、spring.data.jpa.repositories.bootstrap-mode プロパティをそれぞれ deferred または lazy に設定します。遅延または遅延ブートストラップを使用する場合、自動構成された EntityManagerFactoryBuilder (Javadoc) は、コンテキストの AsyncTaskExecutor (Javadoc) (存在する場合) をブートストラップエグゼキュータとして使用します。複数存在する場合は、applicationTaskExecutor という名前のものが使用されます。

遅延ブートストラップまたはレイジーブートストラップを使用する場合は、アプリケーションコンテキストブートストラップフェーズ後の JPA インフラストラクチャへのアクセスを必ず遅延してください。SmartInitializingSingleton (Javadoc) を使用して、JPA インフラストラクチャを必要とする初期化を呼び出すことができます。Spring Bean として作成される JPA コンポーネント (コンバーターなど) の場合は、依存関係の解決を遅延するために ObjectProvider (Javadoc) を使用します (依存関係がある場合)。

Spring Data JPA に関して、ほんの少し触れただけです。詳細については、Spring Data JPA リファレンスドキュメントを参照してください。

Spring Data Envers リポジトリ

Spring Data Envers が使用可能な場合、JPA リポジトリは、一般的な Envers クエリをサポートするように自動構成されます。

Spring Data Envers を使用するには、次の例に示すように、リポジトリが RevisionRepository (Javadoc) から拡張されていることを確認してください。

  • Java

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

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

	Page<Country> findAll(Pageable pageable);

}
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 リファレンスドキュメントを確認してください。

JPA データベースの作成と削除

デフォルトでは、組み込みデータベース(H2、HSQL、Derby)を使用する場合にのみ、JPA データベースが自動的に作成されます。spring.jpa.* プロパティを使用して、JPA 設定を明示的に構成できます。例: テーブルを作成および削除するには、次の行を application.properties に追加します。

  • プロパティ

  • YAML

spring.jpa.hibernate.ddl-auto=create-drop
spring:
  jpa:
    hibernate.ddl-auto: "create-drop"
Hibernate の独自の内部プロパティ名(覚えている場合)は hibernate.hbm2ddl.auto です。spring.jpa.properties.* を使用して、他の Hibernate ネイティブプロパティとともに設定できます(プレフィックスは、エンティティマネージャーに追加する前に削除されます)。次の行は、Hibernate の JPA プロパティの設定例を示しています。
  • プロパティ

  • YAML

spring.jpa.properties.hibernate.globally_quoted_identifiers=true
spring:
  jpa:
    properties:
      hibernate:
        "globally_quoted_identifiers": "true"

上記の例の行は、hibernate.globally_quoted_identifiers プロパティの true の値を Hibernate エンティティマネージャーに渡します。

デフォルトでは、DDL の実行 (または検証) は ApplicationContext (Javadoc) が開始するまで延期されます。

Open EntityManager in View

Web アプリケーションを実行している場合、Spring Boot はデフォルトで OpenEntityManagerInViewInterceptor (Javadoc) を登録して "Open EntityManager in View" パターンを適用し、Web ビューでの遅延読み込みを可能にします。この動作が望ましくない場合は、application.properties で spring.jpa.open-in-view を false に設定する必要があります。

Spring Data JDBC

Spring Data には JDBC のリポジトリサポートが含まれており、CrudRepository (Javadoc) のメソッドの SQL を自動的に生成します。より高度なクエリには、@Query (Javadoc) アノテーションが提供されます。

Spring Boot は、必要な依存関係がクラスパス上にある場合、Spring Data の JDBC リポジトリを自動構成します。これらは、spring-boot-starter-data-jdbc への単一の依存関係を使用してプロジェクトに追加できます。必要に応じて、@EnableJdbcRepositories (Javadoc) アノテーションまたは AbstractJdbcConfiguration (Javadoc) サブクラスをアプリケーションに追加して、Spring Data JDBC の構成を制御できます。

Spring Data JDBC の詳細については、リファレンスドキュメントを参照してください。

H2 の Web コンソールを使用する

H2 データベース (英語) は、Spring Boot が自動構成できるブラウザーベースのコンソール (英語) を提供します。コンソールは、次の条件が満たされると自動構成されます。

  • サーブレットベースの Web アプリケーションを開発しています。

  • com.h2database:h2 はクラスパス上にあります。

  • Spring Boot の開発者ツールを使用しています。

Spring Boot の開発者ツールを使用していないが、H2 のコンソールを引き続き使用したい場合は、spring.h2.console.enabled プロパティを true の値で構成できます。
H2 コンソールは開発中の使用のみを目的としているため、spring.h2.console.enabled が本番環境で true に設定されないように注意する必要があります。

H2 コンソールのパスを変更する

デフォルトでは、コンソールは /h2-console で使用可能です。spring.h2.console.path プロパティを使用して、コンソールのパスをカスタマイズできます。

安全なアプリケーションでの H2 コンソールへのアクセス

H2 Console はフレームを使用し、開発のみを目的としているため、CSRF 保護対策を実装していません。アプリケーションで Spring Security を使用する場合は、次のように構成する必要があります。

  • コンソールに対するリクエストの CSRF 保護を無効にします。

  • コンソールからのレスポンスでヘッダー X-Frame-Options を SAMEORIGIN に設定します。

CSRF およびヘッダー X-Frame-Options の詳細については、Spring Security リファレンスガイドを参照してください。

シンプルなセットアップでは、次のような SecurityFilterChain (Javadoc) を使用できます。

  • Java

  • Kotlin

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.config.annotation.web.configurers.CsrfConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer.FrameOptionsConfig;
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(CsrfConfigurer::disable);
		http.headers((headers) -> headers.frameOptions(FrameOptionsConfig::sameOrigin));
		return http.build();
	}


}
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 保護を無効にするか、Web サイトのフレームを許可すると、重大なセキュリティリスクが発生する可能性があります。
PathRequest.toH2Console() は、コンソールのパスがカスタマイズされている場合にも、正しいリクエストマッチャーを返します。

jOOQ を使用する

jOOQ オブジェクト指向クエリ(jOOQ (英語) )は、データベースから Java コードを生成し、その流れるような API を介して型安全な SQL クエリを作成できる Data Geekery (英語) の人気製品です。Spring Boot では、有償版とオープンソース版の両方を使用できます。

コード生成

jOOQ 型安全クエリを使用するには、データベーススキーマから Java クラスを生成する必要があります。jOOQ ユーザーマニュアル (英語) の指示に従うことができます。jooq-codegen-maven プラグインを使用し、spring-boot-starter-parent 「親 POM」も使用する場合、プラグインの <version> タグを安全に省略できます。SpringBoot 定義バージョン変数(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>

DSLContext を使用する

jOOQ が提供する Fluent API は、DSLContext (英語) インターフェースを通じて開始されます。Spring Boot は、DSLContext (英語) を Spring Bean として自動構成し、アプリケーション DataSource (標準 Javadoc) に接続します。DSLContext (英語) を使用するには、次の例に示すように、それを注入できます。

  • Java

  • Kotlin

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


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

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


}
jOOQ マニュアルでは、DSLContext (英語) を保持するために create という変数を使用する傾向があります。

次の例に示すように、DSLContext (英語) を使用してクエリを構築できます。

  • Java

  • Kotlin

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

jOOQ SQL ダイアレクト

spring.jooq.sql-dialect プロパティが設定されていない限り、Spring Boot はデータソースに使用する SQL ダイアレクトを決定します。Spring Boot がダイアレクトを検出できなかった場合、DEFAULT を使用します。

Spring Boot は、jOOQ のオープンソースバージョンでサポートされているダイアレクトのみを自動構成できます。

jOOQ のカスタマイズ

Configuration (英語) @Bean (Javadoc) を作成する前に呼び出される独自の DefaultConfigurationCustomizer (Javadoc) Bean を定義することで、より高度なカスタマイズを実現できます。これは、自動構成によって適用されるものよりも優先されます。

jOOQ 構成を完全に制御したい場合は、独自の Configuration (英語) @Bean (Javadoc) を作成することもできます。

R2DBC を使用する

Reactive Relational Database Connectivity (R2DBC (英語) ) プロジェクトは、リアクティブプログラミング API をリレーショナルデータベースに導入します。R2DBC の Connection (英語) は、ノンブロッキングデータベース接続を操作するための標準的な方法を提供します。接続は、jdbc の DataSource (標準 Javadoc) に似た ConnectionFactory (英語) を使用して提供されます。

ConnectionFactory (英語) 構成は、spring.r2dbc.* の外部構成プロパティによって制御されます。たとえば、application.properties で次のセクションを宣言できます。

  • プロパティ

  • YAML

spring.r2dbc.url=r2dbc:postgresql://localhost/test
spring.r2dbc.username=dbuser
spring.r2dbc.password=dbpass
spring:
  r2dbc:
    url: "r2dbc:postgresql://localhost/test"
    username: "dbuser"
    password: "dbpass"
Spring Boot は R2DBC の接続ファクトリディスカバリからドライバーを取得するため、ドライバークラス名を指定する必要はありません。
少なくとも URL を指定する必要があります。URL で指定された情報は、個々のプロパティ、つまり nameusernamepassword およびプーリングオプションよりも優先されます。
「使い方ガイド」セクションには、データベースを初期化する方法に関するセクションが含まれています。

ConnectionFactory (英語) によって作成された接続をカスタマイズするには、つまり、主要データベース構成で構成したくない (または構成できない) 特定のパラメーターを設定するには、ConnectionFactoryOptionsBuilderCustomizer (Javadoc) @Bean (Javadoc) を使用できます。次の例は、データベースポートを手動でオーバーライドし、残りのオプションをアプリケーション構成から取得する方法を示しています。

  • Java

  • 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)
public class MyR2dbcConfiguration {

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

}
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

  • Kotlin

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

}
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 (標準 Javadoc) 自動構成はバックオフされます。JDBC DataSource (標準 Javadoc) 自動構成を保持し、リアクティブアプリケーションでブロッキング JDBC API を使用するリスクを許容できる場合は、アプリケーションの @Configuration (Javadoc) クラスに @Import(DataSourceAutoConfiguration.class) を追加して再度有効にします。

組み込みデータベースのサポート

JDBC サポートと同様に、Spring Boot はリアクティブ使用のために組み込みデータベースを自動的に構成できます。接続 URL を提供する必要はありません。次の例に示すように、使用する組み込みデータベースへのビルド依存関係のみを含める必要があります。

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

テストでこの機能を使用している場合、使用するアプリケーションコンテキストの数に関係なく、テストスイート全体で同じデータベースが再利用されることに気付く場合があります。各コンテキストに個別の組み込みデータベースがあることを確認する場合は、spring.r2dbc.generate-unique-name を true に設定する必要があります。

DatabaseClient の使用

DatabaseClient (Javadoc) Bean は自動構成されており、次の例に示すように、独自の Bean に直接自動接続できます。

  • Java

  • Kotlin

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

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

}

Spring Data R2DBC リポジトリ

Spring Data R2DBC リポジトリは、データにアクセスするために定義できるインターフェースです。クエリはメソッド名から自動的に作成されます。例: CityRepository インターフェースは、特定の状態のすべての都市を見つけるために findAllByState(String state) メソッドを宣言できます。

より複雑なクエリの場合、Spring Data の @Query (Javadoc) アノテーションでメソッドにアノテーションを付けることができます。

Spring Data リポジトリは通常、Repository (Javadoc) または CrudRepository (Javadoc) インターフェースから拡張されます。自動構成を使用する場合、自動構成パッケージでリポジトリが検索されます。

次の例は、典型的な Spring Data リポジトリインターフェース定義を示しています。

  • Java

  • Kotlin

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

}
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 リファレンスドキュメントを参照してください。