複数のSpring Bootアプリケーションで同じインメモリH2データベースにアクセスする

複数のSpring Bootアプリケーションで同じインメモリH2データベースにアクセスする

1. 概要

このクイックチュートリアルでは、how to access the same in-memory H2 database from multiple Spring Boot applicationsを示します。

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

2. バックグラウンド

ご存じのように、インメモリデータベースは高速で、アプリケーション内の組み込みモードでよく使用されます。 ただし、インメモリデータベースは、サーバーを再起動してもデータを保持しません。

その他の背景については、the most commonly used in-memory databasesusage of an in-memory database in automated testingに関する記事を確認してください。

3. Mavenの依存関係

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


    
        org.springframework.boot
        spring-boot-starter-data-jpa
    
    
        com.h2database
        h2
    

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の自動構成機能によってoverride the default data sourceを作成しましょう。

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データベースを共有するwe’ll need to use the same properties and values in the other applicationsがあるため、これらのプロパティをオーバーライドすることが重要です。

5. 最初のSpring Bootアプリケーションのブートストラップ

次に、Spring Bootアプリケーションをブートストラップするために、@SpringBootApplication annotationを使用してクラスを作成します。

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

次に、上記で定義したものと同じMaven依存関係を必要とするクライアントアプリケーションのコンポーネントを見てみましょう。

まず、データソースのプロパティを上書きします。 ensure that the port number in the JDBC URL is the same as the one on which H2 is listening for incoming connections in the first application.する必要があります

クライアントアプリケーションの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 annotation:を使用してan 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番目のアプリケーションが期待どおりにデータを印刷することを確認できます。

これがconsole logs of the first Spring Boot application:です

****** 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

そしてここにconsole logs of the second Spring Boot application:があります

****** 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. 結論

この簡単な記事では、access the same in-memory H2 database instance from multiple Spring Boot applicationsを実行する方法を説明しました。

いつものように、実用的なコード例はover on GitHubで利用できます。