Рубрики
Без рубрики

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

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

Автор оригинала: baeldung.

1. Обзор

В этом кратком руководстве мы продемонстрируем , как получить доступ к одной и той же базе данных H2 в памяти из нескольких приложений Spring Boot .

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

2. Предыстория

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

Для получения дополнительной информации, пожалуйста, ознакомьтесь с нашими статьями о наиболее часто используемых базах данных в памяти и использовании базы данных в памяти при автоматизированном тестировании .

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

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

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

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

Затем давайте переопределим источник данных по умолчанию , созданный функцией автоматической настройки 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

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

5. Загрузка первого приложения Spring Boot

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

Во-первых, мы переопределим свойства источника данных. Нам нужно убедиться, что номер порта в URL-адресе JDBC совпадает с тем, на котором 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.

Опять же для простоты мы определяем @SpringBootApplication , содержащий метод initDb с аннотацией @PostConstruct:

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

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

Вот журналы консоли первого приложения 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

А вот журналы консоли второго приложения 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. Заключение

В этой краткой статье мы рассмотрели, как мы можем получить доступ к одному и тому же экземпляру базы данных H2 в памяти из нескольких приложений Spring Boot .

Как всегда, примеры рабочего кода доступны на GitHub .