複数のSpringBootアプリケーションで同じインメモリH2データベースにアクセスする
1. 概要
このクイックチュートリアルでは、複数のSpring Bootアプリケーションから同じインメモリH2データベースにアクセスする方法を示します。
これを行うために、2つの異なるSpring Bootアプリケーションを作成します。 最初のSpringBootアプリケーションはメモリ内のH2インスタンスを開始しますが、2番目のアプリケーションはTCPを介して最初のアプリケーションの埋め込みH2インスタンスにアクセスします。
2. バックグラウンド
ご存知のように、インメモリデータベースはより高速で、アプリケーション内の埋め込みモードで使用されることがよくあります。 ただし、インメモリデータベースは、サーバーの再起動後もデータを保持しません。
その他の背景については、最も一般的に使用されるインメモリデータベースおよび自動テストでのインメモリデータベースの使用に関する記事を確認してください。
3. Mavenの依存関係
この記事の2つのSpringBootアプリケーションには、同じ依存関係が必要です。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
4. H2データソースの設定
まず、最も重要なコンポーネント(インメモリH2データベースのSpring bean)を定義し、TCPポートを介して公開しましょう。
@Bean(initMethod = "start", destroyMethod = "stop")
public Server inMemoryH2DatabaseaServer() throws SQLException {
return Server.createTcpServer(
"-tcp", "-tcpAllowOthers", "-tcpPort", "9090");
}
initMethodおよびdestroyMethodパラメーターで定義されたメソッドは、H2データベースを開始および停止するためにSpringによって呼び出されます。
-tcp パラメーターは、TCPサーバーを使用してH2を起動するようにH2に指示します。 createTcpServerメソッドの3番目と4番目のパラメーターで使用するTCPポートを指定します。
パラメータtcpAllowOthersは、同じホストまたはリモートホストで実行されている外部アプリケーションからのアクセスのためにH2を開きます。
次に、 application.properties ファイルにいくつかのプロパティを追加して、Spring Bootの自動構成機能によって作成されたデフォルトのデータソースをオーバーライドしましょう。
spring.datasource.url=jdbc:h2:mem:mydb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create
同じH2データベースを共有する他のアプリケーションで同じプロパティと値を使用する必要があるため、これらのプロパティをオーバーライドすることが重要です。
5. 最初のSpringBootアプリケーションのブートストラップ
次に、Spring Bootアプリケーションをブートストラップするために、 @ SpringBootApplicationアノテーションを使用してクラスを作成します。
@SpringBootApplication
public class SpringBootApp {
public static void main(String[] args) {
SpringApplication.run(SpringBootApp.class, args);
}
}
すべてが正しく配線されていることをテストするために、コードを追加してテストデータを作成しましょう。
initDb という名前のメソッドを定義し、 @PostConstruct でアノテーションを付けて、メインクラスが初期化されるとすぐにSpringコンテナーがこのメソッドを自動的に呼び出すようにします。
@PostConstruct
private void initDb() {
String sqlStatements[] = {
"drop table employees if exists",
"create table employees(id serial,first_name varchar(255),last_name varchar(255))",
"insert into employees(first_name, last_name) values('Eugen','Paraschiv')",
"insert into employees(first_name, last_name) values('Scott','Tiger')"
};
Arrays.asList(sqlStatements).forEach(sql -> {
jdbcTemplate.execute(sql);
});
// Query test data and print results
}
6. 2番目のSpringBootアプリケーション
次に、上記で定義したものと同じMaven依存関係を必要とするクライアントアプリケーションのコンポーネントを見てみましょう。
まず、データソースのプロパティを上書きします。 JDBC URLのポート番号が、H2が最初のアプリケーションで着信接続をリッスンしているポート番号と同じであることを確認する必要があります。
クライアントアプリケーションのapplication.propertiesファイルは次のとおりです。
spring.datasource.url=jdbc:h2:tcp://localhost:9090/mem:mydb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create
最後に、クライアントのSpringBootアプリケーションのメインクラスを作成します。
ここでも簡単にするために、@PostConstructアノテーションを使用してinitDbメソッドを含む@SpringBootApplicationを定義します。
@SpringBootApplication
public class ClientSpringBootApp {
public static void main(String[] args) {
SpringApplication.run(ClientSpringBootApp.class, args);
}
@PostConstruct
private void initDb() {
String sqlStatements[] = {
"insert into employees(first_name, last_name) values('Donald','Trump')",
"insert into employees(first_name, last_name) values('Barack','Obama')"
};
Arrays.asList(sqlStatements).forEach(sql -> {
jdbcTemplate.execute(sql);
});
// Fetch data using SELECT statement and print results
}
}
7. サンプル出力
これで、両方のアプリケーションを1つずつ実行すると、コンソールログをチェックして、2番目のアプリケーションが期待どおりにデータを出力することを確認できます。
これが最初のSpringBootアプリケーションのコンソールログです:
****** Creating table: Employees, and Inserting test data ******
drop table employees if exists
create table employees(id serial,first_name varchar(255),last_name varchar(255))
insert into employees(first_name, last_name) values('Eugen','Paraschiv')
insert into employees(first_name, last_name) values('Scott','Tiger')
****** Fetching from table: Employees ******
id:1,first_name:Eugen,last_name:Paraschiv
id:2,first_name:Scott,last_name:Tiger
そして、これが2番目のSpringBootアプリケーションのコンソールログです:
****** Inserting more test data in the table: Employees ******
insert into employees(first_name, last_name) values('Donald','Trump')
insert into employees(first_name, last_name) values('Barack','Obama')
****** Fetching from table: Employees ******
id:1,first_name:Eugen,last_name:Paraschiv
id:2,first_name:Scott,last_name:Tiger
id:3,first_name:Donald,last_name:Trump
id:4,first_name:Barack,last_name:Obama
8. 結論
この簡単な記事では、複数のSpringBootアプリケーションから同じインメモリH2データベースインスタンスにアクセスする方法を説明しました。
いつものように、実用的なコード例はGitHubで利用できます。