1.概要

このクイックチュートリアルでは、複数のSpring Bootアプリケーションから同じインメモリH2データベースにアクセスする方法を説明します。

これを行うために、2つの異なるSpring Bootアプリケーションを作成します。最初のSpring BootアプリケーションはインメモリH2インスタンスを起動しますが、2番目のアプリケーションはTCPを介して最初のアプリケーションの組み込みH2インスタンスにアクセスします。

2.背景

私たちが知っているように、インメモリデータベースはより高速で、アプリケーション内の埋め込みモードでよく使われます。ただし、インメモリデータベースでは、サーバーを再起動してもデータは保持されません。

その他の背景については、https://www.baeldung.com/java-in-memory-databases[最も一般的に使用されるインメモリデータベース]およびhttps://www.baeldung.com/spring-を参照してください。 jpa-test-in-memory-database[自動テストにおけるインメモリデータベースの使用法]

3. Mavenの依存関係

この記事の2つのSpring Bootアプリケーションには、同じ依存関係が必要です。

<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

パラメーターは、H2を起動するためにTCPサーバーを使用するように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.最初のSpringブートアプリケーションのブートストラップ

次に、Spring Bootアプリケーションをブートストラップするために、

__ @ SpringBootApplication

__アノテーションを使用してクラスを作成します。

@SpringBootApplication
public class SpringBootApp {
    public static void main(String[]args) {
        SpringApplication.run(SpringBootApp.class, args);
    }
}

すべてが正しく配線されていることをテストするために、テストデータを作成するためのコードを追加しましょう。

メインクラスが初期化されるとすぐにSpringコンテナがこのメソッドを自動的に呼び出すように、

initDb

という名前のメソッドを定義し、それに

__ @ PostConstruct

__soという注釈を付けます。

@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回目のSpring Bootアプリケーション

それでは、クライアントアプリケーションのコンポーネントを見てみましょう。これには、上記と同じ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

最後に、クライアントのSpring Bootアプリケーションのメインクラスを作成します。

再度簡単にするために、

@ 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番目のアプリケーションがデータを正しく印刷することを確認できます。

これが最初のSpring Bootアプリケーションのコンソールログです。

** ** ** ** ** **  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番目のSpring Bootアプリケーションのコンソールログです。

** ** ** ** ** **  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.まとめ

このクイック記事では、複数のSpring Bootアプリケーションから同じインメモリH2データベースインスタンスにアクセスする方法を説明しました。

いつものように、実用的なコード例はhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/spring-boot-h2[GitHubで利用可能]です。