Dev Services for Databases
在开发模式下进行测试或运行时,Quarkus 可以为您提供开箱即用的零配置数据库,我们称之为开发服务。根据数据库类型,您可能需要安装 Docker 才能使用此功能。开发服务支持以下数据库:
-
DB2(容器)(需要license acceptance)
-
Derby (in-process)
-
H2 (in-process)
-
MariaDB (container)
-
Microsoft SQL Server(容器)(需要license acceptance)
-
MySQL (container)
-
Oracle Express Edition (container)
-
PostgreSQL (container)
如果您想使用开发服务,那么您需要做的就是包含您想要数据库类型的相关扩展(反应式或 JDBC,或两者)。不要配置数据库 URL、用户名和密码 - Quarkus 将提供数据库,您可以开始编码,而不用担心配置。 生产数据库需要像正常情况一样进行配置,因此,如果您想在`application.properties`中包含生产数据库配置并继续使用开发服务,则我们建议您使用`%prod.`配置文件来定义您的数据库设置。
Enabling / Disabling Dev Services for Database
用于数据库的开发服务会在开发模式和运行测试时自动启动一个数据库服务器。所以,您不必手动启动一个服务器。应用程序会自动配置。
您可以通过以下方式禁用`application.properties`的自动数据库启动:
quarkus.devservices.enabled=false
# OR
quarkus.datasource.devservices.enabled=false
数据库的开发服务依赖 Docker 来启动服务器(除了已进程方式运行的 H2 和 Derby)。如果您的环境不支持 Docker,您将需要手动启动服务器或连接到已运行服务器。
Proprietary Databases - License Acceptance
如果您使用 DB2 或 MSSQL 等专有数据库,您将需要接受许可协议。为此,在您的项目中创建一个 src/main/resources/container-license-acceptance.txt
文件,并添加一行,其中包含数据库的映像名称和标签。默认情况下,Quarkus 使用当前 Testcontainers 版本的默认图像,如果您尝试启动 Quarkus,结果失败会告诉您确切的图像名称,供您将其添加到该文件中。
示例文件如下所示:
ibmcom/db2:11.5.0.0a mcr.microsoft.com/mssql/server:2022-latest
Reusing Dev Services
General case
在 dev 模式会话或测试套件执行内,只要数据库开发服务的配置(用户名、密码、环境、端口绑定等)没有改变,Quarkus 会始终重复使用它们。
当任何数据库开发服务的配置发生改变时,Quarkus 会始终重启所有数据库开发服务。
当 dev 模式会话或测试套件执行结束时,Quarkus 会(默认)停止所有数据库开发服务。
Reusing Dev Service containers across runs
假设您依赖基于容器的开发服务(与 H2 或 Derby 不同),如果您想不断运行开发服务容器 after a dev mode session or test suite execution 以在下一个 dev 模式会话或测试套件执行中重复使用它们,这是可行的。只需通过在您的 TestContainers configuration file 之一(通常为 ~/.testcontainers.properties
或 C:/Users/myuser/.testcontainers.properties
)中插入此行启用 TestContainers reuse:
testcontainers.reuse.enable=true
即使启用了容器重复使用,只有当容器的启动命令没有改变时才会重复使用容器:相同的环境变量(特别是用户名/密码)、相同的端口绑定、相同的卷装入等。 |
重复使用容器意味着重复使用它们的内部状态,包括数据库架构和表的内容。 如果不希望这样做——以及如果您的测试写入数据库,则可能不希望这样做——考虑 configuring Hibernate ORM appropriately,或使用 Flyway 或 Liquibase。
启用容器重用后,旧容器(尤其是那些配置已过时的容器)可能会无限期地运行,即使在启动新的 Quarkus 开发模式会话或测试套件执行之后也是如此。 在那种情况下,你需要手动停止并移除这些容器。
如果您想为某些 Quarkus 应用程序重复使用容器,但不是全部,或某些开发服务,但不是全部,您可以通过将配置属性 <<`quarkus.datasource.devservices.reuse`/quarkus.datasource."datasource-name".devservices.reuse
,quarkus-datasource_quarkus-datasource-devservices_quarkus-datasource-devservices-reuse>> 设置为 false
来为特定开发服务禁用此功能。
Mapping volumes into Dev Services for Database
将卷从 Docker 主机的文件系统映射到容器很方便,可以提供脚本或配置之类的文件,还可以保留数据库数据并在应用程序重启后重复使用它。
映射卷仅适用于使用基于容器的数据库(如 PostgreSQL)的开发服务。 |
开发服务卷可以映射到文件系统或类路径:
# Using a filesystem volume:
quarkus.datasource.devservices.volumes."/path/from"=/container/to 1
# Using a classpath volume:
quarkus.datasource.devservices.volumes."classpath:./file"=/container/to 2
1 | 本地计算机中的文件或文件夹 "/path/from" 将在容器中的 "/container/to" 中可访问。 |
2 | 使用类路径卷时,位置必须以 "classpath:" 开头。项目类路径中的文件或文件夹 "./file" 将在容器中的 "/container/to" 中可访问。 |
使用类路径卷时,容器将仅被授予读取权限。另一方面,使用文件系统卷时,容器将被授予读取权限和写入权限。
Example of mapping volumes to persist the database data
让我们看一个使用 PostgreSQL 的示例,我们将映射文件系统卷以永久保留数据库数据并使用它:
quarkus.datasource.db-kind=postgresql
quarkus.datasource.devservices.volumes."/local/test/data"=/var/lib/postgresql/data
与数据库供应商相关的适当容器内位置因而异。对于 PostgresSQL 为 “/var/lib/postgresql/data”,但对于 MySQL,您将需要此配置:
quarkus.datasource.db-kind=mysql
quarkus.datasource.devservices.volumes."/local/test/data"=/var/lib/mysql
在启动 Dev Services 时(例如,在测试中或在开发模式中),您将会看到文件夹 "/local/test/data" 将在您的文件系统中创建,其中将包含所有数据库数据。在再次重新运行相同的 dev 服务时,此数据将包含您可能事先创建的所有数据。
在将 Dev Services 与 Hibernate ORM 一起使用时,默认情况下,Quarkus 会在应用程序启动时清除数据库,这将清除 Docker 主机的文件系统上的数据库数据。配置 quarkus.hibernate-orm.database.generation=none
或 quarkus.hibernate-orm.database.generation=validate
以避免此行为。
此外,在启动应用程序时使用 Flyway 迁移您的架构将修改 Docker 主机文件系统上的数据库数据。
Database Vendor Specific Configuration
所有基于容器的服务均使用 Testcontainers 运行,但 Quarkus 未使用 Testcontainers JDBC 驱动程序。因此,即使可以在 application.properties
文件中设置额外的 JDBC URL 特性,也不支持 Testcontainers JDBC 驱动程序支持的特定特性,例如 TC_INITSCRIPT
、TC_INITFUNCTION
、TC_DAEMON
、TC_TMPFS
。
不过,Quarkus 可以支持发送到容器本身的 specific 特性,例如,对于 TC_MY_CNF
便如此,该特性允许覆盖 MariaDB/MySQL 配置文件。
覆盖 MariaDB/MySQL 配置需如下进行:
quarkus.datasource.devservices.container-properties.TC_MY_CNF=testcontainers/mysql-conf
该支持取决于数据库,需要在每个 dev service 中具体实施。
Connect To Database Run as a Dev Service
您可以连接到作为 Dev Service 运行的数据库,就像连接到在 Docker 容器中运行的任何数据库一样。
对于大多数数据库,登录凭证是相同的,除非数据库要求不允许:
Database | Username | Password | Database name |
---|---|---|---|
PostgreSQL、MariaDB、MySQL、IBM Db2、H2 |
|
|
|
Microsoft SQL Server |
|
|
Microsoft SQL Server Testcontainer 不支持定义用户名或数据库名称。它还需要一个强密码。 |
对于支持它的数据库(即除了仅允许覆盖密码的 Microsoft SQL Server 之外的所有数据库),您可以覆盖 Dev Service 使用的数据库名称、用户名和密码。 有关更多信息,请参阅 Configuration Reference。 |
请注意,除非另行配置(见下文),Dev Service 将在随机端口上运行。例如,当您在 Dev Service 中运行 PostgreSQL,且主机上已安装 psql
时,您可以通过以下方式连接:
psql -h localhost -p <random port> -U quarkus
可以通过 docker ps
找到随机端口
docker ps
# returns something like this:
CONTAINER ID IMAGE [..] PORTS [..]
b826e3a168c4 postgres:14.2 [..] 0.0.0.0:49174->5432/tcp, :::49174->5432/tcp [..] 1
1 | 随机端口为 49174 。 |
你可以使用以下方式为数据库 Dev 服务请求一个固定端口:
quarkus.datasource.devservices.port=<your fixed port> 1
quarkus.datasource."datasource-name".devservices.port=<your fixed port> 2
1 | 默认数据源的固定端口。 |
2 | 已命名数据源的固定端口。 |
以下是在 PostgreSQL 中使用 Dev Service 的示例输出:
在标签选项卡中,我们看到 Quarkus 添加了数据源标签,当已启动多个 Dev 服务时,该标签对区分容器时非常有用。 |