1. 概述

本文将探讨如何在H2数据库中执行SQL脚本文件。H2是一个开源的Java数据库,既可以嵌入到Java应用中,也可以作为独立服务器运行。它常被用作测试阶段的内存数据库。

有时我们需要在应用启动前后执行脚本文件来创建表、插入数据或更新数据。本文将介绍几种实现方式。

2. 环境准备

我们将创建一个简单的Spring Boot应用,包含嵌入式H2数据库,然后尝试不同方式执行修改数据库的脚本文件。

2.1. 依赖配置

首先在pom.xml中添加spring-boot-starter-data-jpa依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

这个依赖为Spring Boot应用提供了基础的JPA支持。

接着添加H2数据库依赖:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

2.2. 配置文件

application.properties中配置H2数据库连接:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=none

⚠️ 关键点:这里禁用了自动schema生成(ddl-auto=none),因为我们要通过脚本文件手动创建数据库结构。

3. 在Spring Boot应用中执行脚本

项目搭建完成后,我们来看看在Spring Boot中执行脚本文件的几种方式。有时需要在应用启动时预置数据,比如测试场景。

3.1. 使用默认文件

Spring Boot默认会扫描src/main/resources目录下的schema.sql文件创建schema,并执行同目录下的data.sql文件插入数据。

创建schema.sql文件,包含建表语句:

CREATE TABLE IF NOT EXISTS employee (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL
);

再创建data.sql文件,包含数据插入和更新:

INSERT INTO employee (name) VALUES ('John');
INSERT INTO employee (name) VALUES ('Jane');
UPDATE EMPLOYEE SET NAME = 'Jane Doe' WHERE ID = 2;

应用启动时,Spring Boot会自动执行这些脚本。

3.2. 自定义文件位置

通过修改spring.sql.init.schema-locationsspring.sql.init.data-locations属性,可以指定脚本文件位置。 这在需要区分环境或组织文件结构时很有用。

将脚本文件移到src/main/resources/db目录,更新配置:

spring.sql.init.data-locations=classpath:db/data.sql
spring.sql.init.schema-locations=classpath:db/schema.sql

现在Spring Boot会从db目录加载脚本文件。

3.3. 通过代码执行

也可以通过代码执行脚本,这在需要条件执行或动态逻辑时很有用。在src/main/resources下创建script.sql

UPDATE employee SET NAME = 'John Doe' WHERE ID = 1;
SELECT * FROM employee;

H2驱动提供了RunScript.execute()方法执行脚本。 在主类中添加@PostConstruct方法:

@PostConstruct
public void init() throws SQLException, IOException {
    Connection connection = DriverManager.getConnection(url, user, password);
    ResultSet rs = RunScript.execute(connection, new FileReader(new ClassPathResource("db/script.sql").getFile()));
    log.info("Reading Data from the employee table");
    while (rs.next()) {
        log.info("ID: {}, Name: {}", rs.getInt("id"), rs.getString("name"));
    }
}

@PostConstruct确保在应用上下文初始化后执行此方法。应用启动时会执行脚本并输出:

Data from the employee table:
John Doe
Jane Doe

4. 通过命令行执行脚本

另一种方式是通过命令行执行脚本,这对操作生产数据库很有用。H2提供了RunScript工具类。 使用以下命令:

java -cp /path/to/h2/jar/h2-version.jar org.h2.tools.RunScript -url jdbc:h2:db/server/url -user sa -password password -script script.sql -showResults

参数说明:

  • -cp:指定H2 jar路径
  • -url:数据库URL
  • -user:用户名
  • -password:密码
  • -script:脚本文件路径
  • -showResults:显示执行结果(可选)

⚠️ 踩坑提醒:内存数据库无法跨进程共享。如果使用内存数据库URL,RunScript工具会创建新数据库而非使用Spring Boot创建的数据库。

5. 总结

本文介绍了在H2数据库中执行SQL脚本的多种方式:

  • ✅ Spring Boot默认文件(schema.sql/data.sql
  • ✅ 自定义文件位置
  • ✅ 通过代码执行
  • ✅ 命令行工具执行

完整代码示例可在GitHub获取。


原始标题:Run Queries From a File in H2 Database | Baeldung