使用 MariaDB4j 嵌入 MariaDB
一、簡介
MariaDB是 MySQL 的替代資料庫引擎,由 MySQL 的原始開發人員編寫,可作為直接替代品相容。在本文中,我們將探索MariaDB4j庫,它允許我們將 MariaDB 視為 Java 應用程式中的嵌入式資料庫。
2. 它是如何運作的?
MariaDB4j 的工作原理是打包可立即運行的 MariaDB 資料庫引擎本機版本。它透過許多不同的依賴項來實現這一點。大部分功能存在於ch.vorburger.mariaDB4j:mariaDB4j-core
工件中。然後還有其他工件,每個工件都包含可供使用的 MariaDB 資料庫引擎的副本。此版本可用於 Windows、Linux 和 macOS。
使用MariaDB4j庫時,它會自動確定目前作業系統,然後嘗試將MariaDB資料庫引擎提取到臨時工作目錄中。然後,這將像任何其他應用程式一樣執行。一旦運行,我們就可以像連接一個完整的獨立資料庫一樣連接它。
然後,MariaDB4j 庫負責提取、配置、啟動和停止資料庫引擎。
這是 Testcontainers 等解決方案的替代方案,後者透過將資料庫作為 Docker 容器啟動來運作。這意味著即使在 Docker 不可用或不太適合使用的環境中,我們也能夠使用該資料庫。
3. 命令列使用
我們使用 MariaDB4j 的第一種方式是作為命令列包裝器。它僅支援 Windows 和 Linux,但提供了一種無需完整安裝即可運行資料庫的簡單方法。
為了使用它,我們需要下載提供的 uber mariaDB4j-app.jar
JAR 檔案。我們可以在Maven Central中找到它。在撰寫本文時,最新的可用版本是3.1.0 。其中包含 MariaDB4j 核心程式碼以及適用於 Windows 和 Linux 的資料庫引擎。
下載此檔案後,我們可以像任何其他 Java 應用程式一樣執行 JAR 檔案:
$ java -jar mariaDB4j-app-3.1.0.jar
.....
2024-11-08T07:38:47.867Z INFO 40 --- [pool-9-thread-2] ch.vorburger.exec.ManagedProcess : mariadbd: 2024-11-08 7:38:47 0 [Note] /tmp/MariaDB4j/base/bin/mariadbd: ready for connections.
2024-11-08T07:38:47.868Z INFO 40 --- [pool-9-thread-2] ch.vorburger.exec.ManagedProcess : mariadbd: Version: '10.11.5-MariaDB' socket: '/tmp/MariaDB4j.3307.sock' port: 3307 MariaDB Server
2024-11-08T07:38:47.924Z INFO 40 --- [ main] ch.vorburger.mariadb4j.DB : Database startup complete.
2024-11-08T07:38:48.454Z INFO 40 --- [ main] cvmsboot.MariaDB4jApplication : Started MariaDB4jApplication in 6.589 seconds (process running for 8.281)
Hit Enter to quit...
載入完成後,我們的資料庫就可以使用了。
如果需要,我們也可以使用一些系統屬性來自訂執行。其中最有用的是mariaDB4j.port
,它允許我們控制資料庫偵聽的連接埠號碼。我們也可以使用mariaDB4j.baseDir
來控制 MariaDB 安裝的解壓縮位置,並使用mariaDB4j.dataDir
來控制資料檔案的儲存位置:
$ java -DmariaDB4j.port=13306 -DmariaDB4j.baseDir=/tmp/db -DmariaDB4j.dataDir=/tmp/data -jar mariaDB4j-app-3.1.0.jar
4. 從 Java 使用
更有可能的是,我們希望能夠從我們的應用程式中自動執行 MariaDB。
為此,我們需要將主要的 MariaDB4j 依賴項新增到我們的應用程式中。如果我們使用 Maven,我們可以在pom.xml
檔案中包含此依賴項:
<dependency>
<groupId>ch.vorburger.mariaDB4j</groupId>
<artifactId>mariaDB4j</artifactId>
<version>3.1.0</version>
</dependency>
此時,我們已準備好開始在我們的應用程式中使用它。預設情況下,這將包括 Windows 和 Linux 所需的依賴項,運行預設支援的 MariaDB 版本 - 10.11.5。也可以新增 macOS 依賴項。但是,這還不支援最新版本,需要更多工作才能運行。
一旦我們安裝了依賴項,我們就可以開始使用它了。最簡單的方法是呼叫DB.newEmbeddedDB()
,提供要偵聽的連接埠號碼:
DB db = DB.newEmbeddedDB(0);
此處使用0
將導致系統找到未使用的連接埠。使用任何真實的連接埠號碼都會導致它使用該連接埠號碼。
完成此操作後,我們可以使用db.start()
啟動資料庫並使用db.stop()
停止資料庫:
try {
db.start();
} finally {
db.stop();
}
此時,我們的資料庫正在運作並可供使用。
4.1.配置我們的資料庫
我們也可以提供一些配置,而不是簡單地使用預設設定來運行資料庫。這是使用DBConfigurationBuilder
為我們的資料庫產生配置來完成的。例如,如果我們想指定資料庫的連接埠、資料目錄和基底目錄,我們執行:
DBConfigurationBuilder config = DBConfigurationBuilder.newBuilder();
config.setPort(13306);
config.setDataDir("/tmp/data");
config.setBaseDir("/tmp/db");
DB db = DB.newEmbeddedDB(config.build());
建立DB
實例後,我們就可以像以前一樣使用它。
這也讓我們可以控制所使用的資料庫的版本。我們可以使用DBConfigurationBuilder
物件上的setDatabaseVersion()
方法來指定版本。但是,如果我們這樣做,我們的應用程式必須包含資料庫版本的正確依賴項。
4.2.與資料庫交互
一旦資料庫運行起來,我們現在就需要能夠與它進行互動。 MariaDB4j 提供了幾種不同的方法來實現這一目標。
最簡單的方法是簡單地運行命令,就像我們在 MariaDB 終端機中輸入命令一樣。這可以透過db.run()
指令來完成。使用此命令,我們可以實現資料庫終端可以實現的任何功能 – 包括運行 SQL 命令以及更多以管理為中心的任務:
db.run("show databases");
但請注意,此操作不會傳回任何內容。此命令將輸出列印到標準 Java 輸出:
[2024-11-08 09:37:40,470]-[main] INFO ch.vorburger.mariadb4j.DB - Running a command: show databases
[2024-11-08 09:37:40,470]-[main] INFO ch.vorburger.exec.ManagedProcess - Starting Program [/tmp/MariaDB4j/base/bin/mariadb, --default-character-set=utf8, --socket=/tmp/MariaDB4j.40315.sock] (in working directory /tmp/MariaDB4j/base)
[2024-11-08 09:37:40,535]-[CommonsExecStreamPumper-pool-17-thread-2] INFO ch.vorburger.exec.ManagedProcess - mariadb: Database
[2024-11-08 09:37:40,536]-[CommonsExecStreamPumper-pool-17-thread-2] INFO ch.vorburger.exec.ManagedProcess - mariadb: information_schema
[2024-11-08 09:37:40,536]-[CommonsExecStreamPumper-pool-17-thread-2] INFO ch.vorburger.exec.ManagedProcess - mariadb: mysql
[2024-11-08 09:37:40,536]-[CommonsExecStreamPumper-pool-17-thread-2] INFO ch.vorburger.exec.ManagedProcess - mariadb: performance_schema
[2024-11-08 09:37:40,536]-[CommonsExecStreamPumper-pool-17-thread-2] INFO ch.vorburger.exec.ManagedProcess - mariadb: sys
[2024-11-08 09:37:40,536]-[CommonsExecStreamPumper-pool-17-thread-2] INFO ch.vorburger.exec.ManagedProcess - mariadb: test
[2024-11-08 09:37:40,536]-[CommonsExecStreamPumper-pool-17-thread-2] INFO ch.vorburger.exec.ManagedProcess - mariadb: testing
[2024-11-08 09:37:40,538]-[CommonsExecDefaultExecutorpool-14-thread-1] INFO ch.vorburger.exec.LoggingExecuteResultHandler - Program [/tmp/MariaDB4j/base/bin/mariadb, --default-character-set=utf8, --socket=/tmp/MariaDB4j.40315.sock] (in working directory /tmp/MariaDB4j/base) just exited, with value 0
還有一些輔助方法只包裝db.run()
但可以更輕鬆地執行一些常見任務。例如, db.createDB()
可用來執行指令CREATE DATABASE IF NOT EXISTS:
db.createDB("testing", "testuser", "testpass");
還有db.source()
,我們可以使用它來執行類別路徑中存在的整個 SQL 腳本:
db.createDB("testing", "testuser", "testpass");
db.source("com/baeldung/data/mariadb4j/source.sql", "testuser", "testpass", "testing");
這不是運行單一命令,而是逐行執行整個提供的命令檔。
4.3.與 JDBC 交互
最後,也許與資料庫互動的最有用的方法是使用 JDBC。由於這是一個完全運作的資料庫引擎,我們可以像平常一樣連接到它。我們所需要的只是一個適當的 JDBC 連接字串和憑證。
我們已經了解如何在資料庫引擎中使用憑證建立資料庫 - 使用db.createDB()
。完成後,我們可以呼叫db.getConfiguration().getURL()
來提供用於與資料庫通訊的連接字串:
db.createDB("testing", "testuser", "testpass");
assertEquals("jdbc:mariadb://localhost:13306/testing", db.getConfiguration().getURL("testing"));
這會產生具有正確主機名稱和連接埠的 URL,即使連接埠是隨機分配的。
完成此操作後,我們就可以使用任何標準 JDBC 實用程式與資料庫進行通訊:
String url = db.getConfiguration().getURL("testing");
try (Connection conn = DriverManager.getConnection(url, "testuser", "testpass")) {
// Use JDBC Connection here.
}
我們可以使用任何其他 JDBC 相容工具(例如 JPA、JdbcTemplate 或其他任何工具)同樣出色地完成此任務。
請注意,這假設我們在類別路徑上有可用的MariaDB JDBC 驅動程序,就像連接到任何其他 MariaDB 實例時一樣。
5. 在 JUnit 測試中使用
MariaDB4j 的一個非常強大的用途是能夠與我們測試中的真實但短暫的資料庫集成,而生產應用程式則指向永久資料庫。 MariaDB4j 正是為此目的提供了 JUnit4 規則。
使用標準@Rule
註釋在每個測試方法運行之前啟動資料庫並在運行之後關閉它:
@Rule
public MariaDB4jRule dbRule = new MariaDB4jRule(0);
然後,我們可以根據需要從測試中存取資料庫:
@Test
public void whenRunningATest_thenTheDbIsAvailable() throws Exception {
try (Connection conn = DriverManager.getConnection(dbRule.getURL(), "root", "")) {
// Use JDBC Connection here.
}
}
這將圍繞每個單獨的測試方法啟動和停止資料庫,這為我們提供了隔離,但以效能為代價。相反,我們可以使用@ClassRule
註解:
@ClassRule
public static MariaDB4jRule dbRule = new MariaDB4jRule(0);
這將為整個測試類別啟動資料庫一次,而不是為每個方法啟動資料庫一次。這給我們帶來了明顯的性能改進,但存在測試之間可能出現洩漏的風險
六、總結
這是對 MariaDB4j 的快速介紹。我們已經看到了一些可以用來輕鬆啟動 MariaDB 資料庫以供本地使用的方法。該庫可以做更多事情,包括與 Maven 直接整合以及在 Spring Boot 中輕鬆使用。
與往常一樣,本文中的所有範例都可以在 GitHub 上找到。