1. 概述
本快速教程將演示如何從多個 Spring Boot 應用程序訪問相同的內存中 H2 數據庫。
為此,我們將創建兩個獨立的 Spring Boot 應用程序。第一個 Spring Boot 應用程序將啓動一個內存中 H2 實例,而第二個應用程序將通過 TCP 協議訪問第一個應用程序的嵌入式 H2 實例。
2. 背景
我們知道,內存數據庫比傳統數據庫快,並且經常在應用程序的嵌入模式中使用。然而,內存數據庫在服務器重啓後不會持久化數據。
為了獲取更多背景信息,請查看我們關於最常用的內存數據庫以及內存數據庫在自動化測試中的使用情況的文章。
3. Maven 依賴項
本文檔中使用的兩個 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");
}由<em>initMethod</em>和<em>destroyMethod</em>參數定義的⽅法,由 Spring 調用以啓動和停止 H2 數據庫。
<em>-tcp</em> 參數指示 H2 使用 TCP 服務器啓動 H2。我們在 <em>createTcpServer</em> 方法的第三和第四個參數中指定要使用的 TCP 端口。
<em>tcpAllowOthers</em> 參數允許 H2 從同一主機或遠程主機上運行的外部應用程序訪問。
接下來,讓我們通過在 <em>application.properties</em> 文件中添加一些屬性來覆蓋 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 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 依賴項。
首先,我們將覆蓋數據源屬性。我們需要確保 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 應用程序的主類。
再次為了簡化,我們定義了一個帶有 @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:Obama8. 結論
在本文中,我們瞭解到如何從多個 Spring Boot 應用程序訪問相同的內存中 H2 數據庫實例。