如何在 JUnit 测试容器中的 MySQLContainer 中导入 sql 转储文件

How to import sql dump file in MySQLContainer in JUnit test containers

我有一个 Mysql 的测试容器,我需要在容器启动后导入转储文件。我尝试了以下两个选项。

public class AbstractTest {

    public static MySQLContainer<?> mySQLContainer = new MySQLContainer<>("mysql:5.7");

    static {
        mySQLContainer
            .withDatabaseName("myDatabase")
            .withCopyFileToContainer(
                MountableFile.forClasspathResource("init.sql", 0744),
                "init.sql")
            .withUsername("root")
            .withPassword("root")
            .start();
    }

    @PostConstruct
    @SneakyThrows
    public void init() {
       option 1 // mySQLContainer.execInContainer("mysql -u root -proot myDatabase < init.sql");
       option 2 // mySQLContainer.execInContainer("mysql", "-u", "root", "-proot", "myDatabase", "<", "init.sql");
    }
   ////
}

仍然没有成功 - 看起来 mysql 无法正确解析我的命令,因为我得到下一个答案:

mysql  Ver 14.14 Distrib 5.7.35, for Linux (x86_64) using  EditLine wrapper
Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Usage: mysql [OPTIONS] [database]
  -?, --help          Display this help and exit.
  -I, --help          Synonym for -?
  --auto-rehash       Enable automatic rehashing. One doesn't need to use
                      'rehash' to get table and field completion, but startup
////.....

如果使用下一个命令

  option 2 // mySQLContainer.execInContainer("mysql", "-u", "root", "-proot");

效果很好,但这不是我想要的

mysql -u root -proot mydatabase < init.sql 命令工作正常,如果我只是通过 bash 从 cli 连接到容器。

所以我的问题 - 如何通过执行图像中的命令将 SQL 转储文件导入 JUnit 测试容器中的 MySQLContainer?

更新: 我发现解析“<”符号有问题。 所以,基本上这在 CLI 中运行良好:

docker exec -i  mycontainer mysql -uroot -proot myDatabase < init.sql

但这不适用于 Java:

mySQLContainer.execInContainer("mysql","-uroot","-proot","myDatabase","<","init.sql");

您需要 applications.properties 适合 MySql,例如:

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_example
spring.datasource.username=springuser
spring.datasource.password=ThePassword
spring.datasource.driver-class-name =com.mysql.jdbc.Driver
#spring.jpa.show-sql: true

然后您可以在 /src/test/resources 中添加一个 data.sql,它将自动成为 运行。

MySQL如果你把它放在一个特殊的路径,可以自动加载一个转储文件。

来自 MySQL Docker image 的文档:

When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. You can easily populate your mysql services by mounting a SQL dump into that directory and provide custom images with contributed data. SQL files will be imported by default to the database specified by the MYSQL_DATABASE variable.

所以最简单的方法是将文件复制到那里:

.withCopyFileToContainer(MountableFile.forClasspathResource("init.sql"), "/docker-entrypoint-initdb.d/schema.sql")