Dev Services for Databases

在开发模式下进行测试或运行时,Quarkus 可以为您提供开箱即用的零配置数据库,我们称之为开发服务。根据数据库类型,您可能需要安装 Docker 才能使用此功能。开发服务支持以下数据库:

When testing or running in dev mode Quarkus can provide you with a zero-config database out of the box, a feature we refer to as Dev Services. Depending on your database type you may need Docker installed in order to use this feature. Dev Services is supported for the following databases:

  • DB2 (container) (requires license_acceptance)

  • Derby (in-process)

  • H2 (in-process)

  • MariaDB (container)

  • Microsoft SQL Server (container) (requires license_acceptance)

  • MySQL (container)

  • Oracle Express Edition (container)

  • PostgreSQL (container)

如果您想使用开发服务,那么您需要做的就是包含您想要数据库类型的相关扩展(反应式或 JDBC,或两者)。不要配置数据库 URL、用户名和密码 - Quarkus 将提供数据库,您可以开始编码,而不用担心配置。

If you want to use Dev Services then all you need to do is include the relevant extension for the type of database you want (either reactive or JDBC, or both). Don’t configure a database URL, username and password - Quarkus will provide the database and you can just start coding without worrying about config.

生产数据库需要像正常情况一样进行配置,因此,如果您想在`application.properties`中包含生产数据库配置并继续使用开发服务,则我们建议您使用`%prod.`配置文件来定义您的数据库设置。

Production databases need to be configured as normal, so if you want to include a production database config in your application.properties and continue to use Dev Services we recommend that you use the %prod. profile to define your database settings.

Enabling / Disabling Dev Services for Database

用于数据库的开发服务会在开发模式和运行测试时自动启动一个数据库服务器。所以,您不必手动启动一个服务器。应用程序会自动配置。

Dev Services for databases automatically starts a database server in dev mode and when running tests. So, you don’t have to start a server manually. The application is configured automatically.

您可以通过以下方式禁用`application.properties`的自动数据库启动:

You can disable the automatic database start in application.properties via:

quarkus.devservices.enabled=false
# OR
quarkus.datasource.devservices.enabled=false

数据库的开发服务依赖 Docker 来启动服务器(除了已进程方式运行的 H2 和 Derby)。如果您的环境不支持 Docker,您将需要手动启动服务器或连接到已运行服务器。

Dev Services for databases relies on Docker to start the server (except for H2 and Derby which are run in process). If your environment does not support Docker, you will need to start the server manually, or connect to an already running server.

Proprietary Databases - License Acceptance

如果您使用 DB2 或 MSSQL 等专有数据库,您将需要接受许可协议。为此,在您的项目中创建一个 src/main/resources/container-license-acceptance.txt 文件,并添加一行,其中包含数据库的映像名称和标签。默认情况下,Quarkus 使用当前 Testcontainers 版本的默认图像,如果您尝试启动 Quarkus,结果失败会告诉您确切的图像名称,供您将其添加到该文件中。

If you are using a proprietary database such as DB2 or MSSQL you will need to accept the license agreement. To do this create a src/main/resources/container-license-acceptance.txt files in your project and add a line with the image name and tag of the database. By default, Quarkus uses the default image for the current version of Testcontainers, if you attempt to start Quarkus the resulting failure will tell you the exact image name in use for you to add to the file.

示例文件如下所示:

An example file is shown below:

src/main/resources/container-license-acceptance.txt
ibmcom/db2:11.5.0.0a
mcr.microsoft.com/mssql/server:2022-latest

Reusing Dev Services

General case

在 dev 模式会话或测试套件执行内,只要数据库开发服务的配置(用户名、密码、环境、端口绑定等)没有改变,Quarkus 会始终重复使用它们。

Within a dev mode session or test suite execution, Quarkus will always reuse database Dev Services as long as their configuration (username, password, environment, port bindings, …​) did not change.

当任何数据库开发服务的配置发生改变时,Quarkus 会始终重启所有数据库开发服务。

When the configuration of any database Dev Services changes, Quarkus will always restart all database Dev Services.

当 dev 模式会话或测试套件执行结束时,Quarkus 会(默认)停止所有数据库开发服务。

When a dev mode session or test suite execution ends, Quarkus will (by default) stop all database Dev Services.

Reusing Dev Service containers across runs

假设您依赖基于容器的开发服务(与 H2 或 Derby 不同),如果您想不断运行开发服务容器 after a dev mode session or test suite execution 以在下一个 dev 模式会话或测试套件执行中重复使用它们,这是可行的。只需通过在您的 TestContainers configuration file 之一(通常为 ~/.testcontainers.propertiesC:/Users/myuser/.testcontainers.properties)中插入此行启用 TestContainers reuse

Assuming you rely on Dev Services based on containers (unlike H2 or Derby), if you want to keep Dev Service containers running after a dev mode session or test suite execution to reuse them in the next dev mode session or test suite execution, this is possible as well. Just enable TestContainers reuse by inserting this line in one of your TestContainers configuration file (generally ~/.testcontainers.properties or C:/Users/myuser/.testcontainers.properties):

testcontainers.reuse.enable=true

即使启用了容器重复使用,只有当容器的启动命令没有改变时才会重复使用容器:相同的环境变量(特别是用户名/密码)、相同的端口绑定、相同的卷装入等。

Even with container reuse enabled, containers will only be reused if their startup command did not change: same environment variables (username/password in particular), same port bindings, same volume mounts, …​

重复使用容器意味着重复使用它们的内部状态,包括数据库架构和表的内容。

Reusing containers implies reusing their internal state, including the database schema and the content of tables.

如果不希望这样做——以及如果您的测试写入数据库,则可能不希望这样做——考虑 configuring Hibernate ORM appropriately,或使用 FlywayLiquibase

If that’s not what you want — and if your tests write to the database, that’s probably not what you want — consider configuring Hibernate ORM appropriately, or using Flyway or Liquibase.

启用容器重用后,旧容器(尤其是那些配置已过时的容器)可能会无限期地运行,即使在启动新的 Quarkus 开发模式会话或测试套件执行之后也是如此。

With container reuse enabled, old containers (especially with obsolete configuration) might be left running indefinitely, even after starting a new Quarkus dev mode session or test suite execution.

在那种情况下,你需要手动停止并移除这些容器。

In that case, you will need to stop and remove these containers manually.

如果您想为某些 Quarkus 应用程序重复使用容器,但不是全部,或某些开发服务,但不是全部,您可以通过将配置属性 <<`quarkus.datasource.devservices.reuse`/quarkus.datasource."datasource-name".devservices.reuse,quarkus-datasource_quarkus-datasource-devservices_quarkus-datasource-devservices-reuse>> 设置为 false 来为特定开发服务禁用此功能。

If you want to reuse containers for some Quarkus applications but not all of them, or some Dev Services but not all of them, you can disable this feature for a specific Dev Service by setting the configuration property <<`quarkus.datasource.devservices.reuse`/quarkus.datasource."datasource-name".devservices.reuse,quarkus-datasource_quarkus-datasource-devservices_quarkus-datasource-devservices-reuse>> to false.

Mapping volumes into Dev Services for Database

将卷从 Docker 主机的文件系统映射到容器很方便,可以提供脚本或配置之类的文件,还可以保留数据库数据并在应用程序重启后重复使用它。

Mapping volumes from the Docker host’s filesystem to the containers is handy to provide files like scripts or configuration, but also to preserve database data and reuse it after an application restart.

映射卷仅适用于使用基于容器的数据库(如 PostgreSQL)的开发服务。

Mapping volumes will only work in Dev Services with a container-based database like PostgreSQL.

开发服务卷可以映射到文件系统或类路径:

Dev Services volumes can be mapped to the filesystem or the classpath:

# 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 The file or folder "/path/from" from the local machine will be accessible at "/container/to" in the container.
2 When using classpath volumes, the location has to start with "classpath:". The file or folder "./file" from the project’s classpath will be accessible at "/container/to" in the container.

使用类路径卷时,容器将仅被授予读取权限。另一方面,使用文件系统卷时,容器将被授予读取权限和写入权限。

when using a classpath volume, the container will only be granted read permission. On the other hand, when using a filesystem volume, the container will be granted read and write permission.

Example of mapping volumes to persist the database data

让我们看一个使用 PostgreSQL 的示例,我们将映射文件系统卷以永久保留数据库数据并使用它:

Let’s see an example using PostgreSQL where we’ll map a file system volume to keep the database data permantently and use it:

quarkus.datasource.db-kind=postgresql
quarkus.datasource.devservices.volumes."/local/test/data"=/var/lib/postgresql/data

与数据库供应商相关的适当容器内位置因而异。对于 PostgresSQL 为 “/var/lib/postgresql/data”,但对于 MySQL,您将需要此配置:

The appropriate in-container location varies depending on the database vendor. For PostgresSQL is "/var/lib/postgresql/data", but for MySQL, you would need this configuration instead:

quarkus.datasource.db-kind=mysql
quarkus.datasource.devservices.volumes."/local/test/data"=/var/lib/mysql

在启动 Dev Services 时(例如,在测试中或在开发模式中),您将会看到文件夹 "/local/test/data" 将在您的文件系统中创建,其中将包含所有数据库数据。在再次重新运行相同的 dev 服务时,此数据将包含您可能事先创建的所有数据。

When starting Dev Services (for example, in tests or in dev mode), you will see that the folder "/local/test/data" will be created at your file sytem and that will contain all the database data. When rerunning again the same dev services, this data will contain all the data you might have created beforehand.

在将 Dev Services 与 Hibernate ORM 一起使用时,默认情况下,Quarkus 会在应用程序启动时清除数据库,这将清除 Docker 主机的文件系统上的数据库数据。配置 quarkus.hibernate-orm.database.generation=nonequarkus.hibernate-orm.database.generation=validate 以避免此行为。

When using Dev Services with Hibernate ORM, by default Quarkus will wipe out the database on application startup, which will wipe out the database data on your Docker host’s filesystem. Configure quarkus.hibernate-orm.database.generation=none or quarkus.hibernate-orm.database.generation=validate to avoid this behavior.

此外,在启动应用程序时使用 Flyway 迁移您的架构将修改 Docker 主机文件系统上的数据库数据。

Also, using Flyway to migrate your schema when starting the application will modify the database data on your Docker hosts’s file system.

Database Vendor Specific Configuration

所有基于容器的服务均使用 Testcontainers 运行,但 Quarkus 未使用 Testcontainers JDBC 驱动程序。因此,即使可以在 application.properties 文件中设置额外的 JDBC URL 特性,也不支持 Testcontainers JDBC 驱动程序支持的特定特性,例如 TC_INITSCRIPTTC_INITFUNCTIONTC_DAEMONTC_TMPFS

All services based on containers are run using Testcontainers but Quarkus is not using the Testcontainers JDBC driver. Thus, even though extra JDBC URL properties can be set in your application.properties file, specific properties supported by the Testcontainers JDBC driver such as TC_INITSCRIPT, TC_INITFUNCTION, TC_DAEMON, TC_TMPFS are not supported.

不过,Quarkus 可以支持发送到容器本身的 specific 特性,例如,对于 TC_MY_CNF 便如此,该特性允许覆盖 MariaDB/MySQL 配置文件。

Quarkus can support specific properties sent to the container itself though, e.g. this is the case for TC_MY_CNF which allows to override the MariaDB/MySQL configuration file.

覆盖 MariaDB/MySQL 配置需如下进行:

Overriding the MariaDB/MySQL configuration would be done as follows:

quarkus.datasource.devservices.container-properties.TC_MY_CNF=testcontainers/mysql-conf

该支持取决于数据库,需要在每个 dev service 中具体实施。

This support is database specific and needs to be implemented in each dev service specifically.

Connect To Database Run as a Dev Service

您可以连接到作为 Dev Service 运行的数据库,就像连接到在 Docker 容器中运行的任何数据库一样。

You can connect to a database running as a Dev Service as you would do with any database running inside a Docker container.

对于大多数数据库,登录凭证是相同的,除非数据库要求不允许:

Login credentials are the same for most databases, except when the database requirements don’t allow it:

Database Username Password Database name

PostgreSQL, MariaDB, MySQL, IBM Db2, H2

quarkus for the default datasource or name of the datasource

quarkus

quarkus

Microsoft SQL Server

SA

Quarkus123

Microsoft SQL Server Testcontainer 不支持定义用户名或数据库名称。它还需要一个强密码。

The Microsoft SQL Server Testcontainer doesn’t support defining the username or database name. It also requires a strong password.

对于支持它的数据库(即除了仅允许覆盖密码的 Microsoft SQL Server 之外的所有数据库),您可以覆盖 Dev Service 使用的数据库名称、用户名和密码。

For databases supporting it (i.e. all of them except Microsoft SQL Server for which it is only possible to override the password), you can override the database name, username and password used by the Dev Service.

有关更多信息,请参阅 Configuration Reference

See Configuration Reference for more information.

请注意,除非另行配置(见下文),Dev Service 将在随机端口上运行。例如,当您在 Dev Service 中运行 PostgreSQL,且主机上已安装 psql 时,您可以通过以下方式连接:

Keep in mind that, except if configured otherwise (see below), a Dev Service runs on a random port. For instance, when you run PostgreSQL as a Dev Service and have psql installed on the host, you can connect via:

psql -h localhost -p <random port> -U quarkus

可以通过 docker ps 找到随机端口

The random port can be found with 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 The random port is 49174.

你可以使用以下方式为数据库 Dev 服务请求一个固定端口:

You can require a fixed port for a database Dev Service using:

quarkus.datasource.devservices.port=<your fixed port> 1

quarkus.datasource."datasource-name".devservices.port=<your fixed port> 2
1 Fixed port for the default datasource.
2 Fixed port for a named datasource.

docker ps 允许使用 --format 参数高级检索容器信息。例如,要获取正在运行的容器 ID、图像、标签和端口,可以使用以下命令:

docker ps allows for more advanced retrieval of container information using the --format argument. For example, to get the running container ID, the image, the labels and the ports, the following command can be used:

docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Labels}}\t{{.Ports}}

以下是在 PostgreSQL 中使用 Dev Service 的示例输出:

An example output using Dev Services for PostgreSQL is the following:

CONTAINER ID   IMAGE          LABELS                                                                        PORTS
a7034c91a392   postgres:14    org.testcontainers.sessionId=xyz,datasource=default,org.testcontainers=true   0.0.0.0:49154->5432/tcp, :::49154->5432/tcp

在标签选项卡中,我们看到 Quarkus 添加了数据源标签,当已启动多个 Dev 服务时,该标签对区分容器时非常有用。

In the labels tab, we see that Quarkus added the datasource label, which can be very useful in differentiating containers when multiple Dev Services have been started.

Configuration Reference

Dev Services for Databases 支持以下配置选项:

Dev Services for Databases support the following configuration options:

Unresolved directive in databases-dev-services.adoc - include::{generated-dir}/config/quarkus-datasource_quarkus.datasource.devservices.adoc[]