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 .