使用 Spring Boot Test @Sql 注解通过掩码描述文件的方法

在 Spring Boot 测试中,我们经常使用 @Sql 注解来执行 SQL 脚本,以便在测试前准备数据或在测试后清理数据。 通常的用法如下:

@Sql(scripts = "/folder/my_favourite_script.sql")
@Test
public void myTest() {
    // 测试逻辑
}

然而,当需要执行大量 SQL 文件时,例如一个目录中有 1000 个 SQL 文件,直接在 @Sql 注解中列出所有文件显得非常繁琐。 期望能够使用文件掩码,例如 /folder/*.sql,来一次性指定所有 SQL 文件。 不幸的是,@Sql 注解本身并不支持这种文件掩码的功能。

那么,该如何解决这个问题呢? 目前主要有两种方案:

1. 使用编程方式执行 SQL 脚本 (适用于 PostgreSQL 等数据库)

由于 @Sql 注解不支持文件掩码,我们可以通过编程的方式读取 SQL 文件并执行。 这需要我们注入 DataSource 对象,并使用它来执行 SQL 脚本。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.init.ScriptUtils;
import javax.sql.DataSource;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Autowired
private DataSource dataSource;

public void executeSqlScripts(String folderPath) throws SQLException, IOException {
    try (Connection connection = dataSource.getConnection()) {
        List sqlFiles = Files.list(Paths.get(folderPath))
                .filter(path -> path.toString().endsWith(".sql"))
                .collect(Collectors.toList());

        for (Path sqlFile : sqlFiles) {
            ScriptUtils.executeSqlScript(connection, new org.springframework.core.io.FileSystemResource(sqlFile.toFile()));
        }
    }
}

@Test
public void myTest() throws SQLException, IOException {
    executeSqlScripts("src/test/resources/folder"); // 替换为你的 SQL 文件目录
    // 测试逻辑
}

注意事项:

  • 确保已经注入了 DataSource 对象。
  • folderPath 需要替换为实际的 SQL 文件目录。
  • 需要处理 SQLException 和 IOException 异常

  • 此方法适用于大多数数据库,例如 PostgreSQL。

2. 使用 H2 数据库的 RUNSCRIPT 命令

如果测试中使用的是 H2 数据库,可以利用其 RUNSCRIPT 命令来批量执行 SQL 文件。 首先,创建一个名为 scripts.sql 的文件,并将所有需要执行的 SQL 文件路径写入其中,每行一个 RUNSCRIPT 命令。

-- scripts.sql
RUNSCRIPT FROM 'file1.sql';
RUNSCRIPT FROM 'file2.sql';
RUNSCRIPT FROM 'file3.sql';
-- ...

然后,在 @Sql 注解中指定该 scripts.sql 文件。

@Sql("scripts.sql")
@Test
public void myTest() {
    // 测试逻辑
}

注意事项:

  • file1.sql、file2.sql 等需要替换为实际的 SQL 文件路径,可以使用相对路径或绝对路径。
  • scripts.sql 文件需要放置在 src/test/resources 目录下或者其他 Spring Boot 可以找到的资源路径下。
  • 此方法仅适用于 H2 数据库。

总结

虽然 @Sql 注解本身不支持文件掩码,但我们可以通过编程方式或利用数据库特定的命令来实现批量执行 SQL 文件的目的。 选择哪种方案取决于所使用的数据库和具体的测试需求。 如果使用 PostgreSQL 等数据库,推荐使用编程方式,灵活性更高; 如果使用 H2 数据库,则可以使用 RUNSCRIPT 命令,更加简洁。