Доступ к одной и той же базе данных H2 в нескольких приложениях Spring Boot

Доступ к одной и той же базе данных H2 в нескольких приложениях Spring Boot

1. обзор

В этом кратком руководстве мы продемонстрируемhow to access the same in-memory H2 database from multiple Spring Boot applications.

Для этого мы создадим два разных приложения Spring Boot. Первое приложение Spring Boot запустит экземпляр H2 в памяти, а второе получит доступ к встроенному экземпляру H2 первого приложения через TCP.

2. Фон

Как мы знаем, база данных в памяти быстрее и часто используется во встроенном режиме в приложении. Однако база данных в памяти не сохраняет данные после перезапуска сервера.

Дополнительные сведения см. В наших статьях оthe most commonly used in-memory databases иusage of an in-memory database in automated testing.

3. Зависимости Maven

Два приложения Spring Boot в этой статье требуют одинаковых зависимостей:


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

4. Настройка источника данных H2

Во-первых, давайте определим наиболее важный компонент - компонент Spring для базы данных H2 в памяти - и представим его через порт TCP:

@Bean(initMethod = "start", destroyMethod = "stop")
public Server inMemoryH2DatabaseaServer() throws SQLException {
    return Server.createTcpServer(
      "-tcp", "-tcpAllowOthers", "-tcpPort", "9090");
}

Методы, определенные параметрамиinitMethod иdestroyMethod, вызываются Spring для запуска и остановки базы данных H2.

Параметр-tcp указывает H2 использовать TCP-сервер для запуска H2. Мы указываем TCP-порт, который будет использоваться в третьем и четвертом параметрах методаcreateTcpServer.

ПараметрtcpAllowOthers открывает H2 для доступа из внешних приложений, работающих на том же хосте или удаленных хостах.

Затем давайте создадимoverride the default data source функцией автоконфигурации Spring Boot, добавив несколько свойств в файлapplication.properties:

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

Важно переопределить эти свойства, потому чтоwe’ll need to use the same properties and values in the other applications хотят использовать одну и ту же базу данных H2.

5. Начальная загрузка первого весеннего загрузочного приложения

Затем, чтобы запустить наше приложение 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. Второе приложение Spring Boot

Теперь давайте посмотрим на компоненты клиентского приложения, для которого требуются те же зависимости 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.

Снова для простоты мы определяем метод@SpringBootApplication c, содержащийan initDb, с помощью@PostConstruct annotation:

@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. Пример вывода

Теперь, когда мы запускаем оба приложения по одному, мы можем проверить журналы консоли и убедиться, что второе приложение печатает данные, как и ожидалось.

Вот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.