1. 引言
H2数据库引擎是基于Java的流行开源数据库。在这个简短的教程中,我们将学习如何在连接H2内存数据库时自动创建模式。
2. 什么是H2?
H2数据库引擎是一个基于Java的SQL和JDBC兼容的数据库。 它有一些与其他关系型数据库不同的特性:
- 存储:它可以作为纯内存数据库或使用文件系统运行。
- 模式:以独立服务器或嵌入到其他应用程序中运行。
这些特性使H2成为开发和测试的理想选择。然而,由于其临时性质,它也可能带来一些挑战。
当连接到H2内存数据库时,可能不存在模式。 这是因为内存数据库是临时的,只有当它们所在的程序运行时才存在。一旦应用程序终止,内存数据库的所有内容都将丢失。
接下来,我们将探讨几种初始化H2内存数据库的方法。
3. 在H2中自动创建模式
对于H2内存数据库,有多种方法可以自动创建模式。每种方法都有其优缺点,选择哪种取决于多个因素。
3.1. 基于Java
下面的示例展示了如何使用纯Java代码和JDBC初始化内存H2数据库。这对于不使用Spring或其他提供数据库连接的框架的应用程序是一个不错的选择:
Connection conn = DriverManager.getConnection(
"jdbc:h2:mem:baeldung;INIT=CREATE SCHEMA IF NOT EXISTS baeldung",
"admin",
"password");
在上述示例中,我们使用连接URL指定要创建的模式。 我们还可以传递额外的命令来进一步初始化数据库:
Connection conn = DriverManager.getConnection(
"jdbc:h2:mem:baeldung;INIT=CREATE SCHEMA IF NOT EXISTS baeldung\\;SET SCHEMA baeldung;CREATE TABLE users (name VARCHAR(100) NOT NULL, email VARCHAR(100) NOT NULL);",
"admin",
"password");
由于所有这些命令可能会使URL难以阅读,H2还支持通过引用SQL文件初始化内存数据库。 首先,我们创建包含初始化语句的文件:
CREATE SCHEMA IF NOT EXISTS baeldung;
SET SCHEMA baeldung;
CREATE TABLE users (name VARCHAR(100) NOT NULL, email VARCHAR(100) NOT NULL);
然后,我们可以使用稍有不同的连接URL引用文件:
Connection conn = DriverManager.getConnection(
"jdbc:h2:mem:baeldung;INIT=RUNSCRIPT FROM 'h2init.sql';",
"admin",
"password");
3.2. Spring Boot
在使用Spring Boot应用程序时,我们也可以利用熟悉的Spring数据属性来初始化H2内存数据库。
首先,我们可以像上面一样,在URL本身中提供所有初始化语句。我们首先定义H2数据源的Spring属性:
spring.datasource.url=jdbc:h2:mem:baeldung;INIT=CREATE SCHEMA IF NOT EXISTS baeldung\\;SET SCHEMA baeldung;
然后,我们可以像正常应用程序那样使用默认的DataSource
bean:
public void initDatabaseUsingSpring(@Autowired DataSource ds) {
try (Connection conn = ds.getConnection()) {
conn.createStatement().execute("create table users (name VARCHAR(100) NOT NULL, email VARCHAR(100) NOT NULL);");
conn.createStatement().execute("insert into users (name, email) values ('Mike', '[email protected]')");
}
catch (Exception e) {
e.printStackTrace();
}
}
与纯Java代码类似,我们也可以在连接URL中引用包含所有初始化语句的SQL文件。我们只需要更新我们的属性:
spring.datasource.url=jdbc:h2:mem:baeldung;INIT=RUNSCRIPT FROM 'src/main/resources/h2init.sql';
值得注意的是,H2不会通过Spring Boot加载资源。 因此,我们必须在应用运行的实际上下文中引用文件路径。
现在,我们可以像以前一样使用DataSource
,而无需先初始化模式:
private void initDatabaseUsingSpring(@Autowired DataSource ds) {
try (Connection conn = ds.getConnection()) {
conn.createStatement().execute("insert into users (name, email) values ('Mike', '[email protected]')");
}
catch (Exception e) {
e.printStackTrace();
}
}
最后,当使用Spring Boot时,我们还可以利用SQL初始化模式,而不依赖H2的功能。我们只需将初始化文件重命名为data.sql
,并稍微调整属性:
spring.datasource.url=jdbc:h2:mem:baeldung
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=admin
spring.datasource.password=password
spring.sql.init.mode=embedded
需要注意的是,我们的属性并未提及模式或初始化文件。
3.3. Spring XML
此外,如果我们使用纯Spring XML配置DataSource
,我们也可以在那里包含初始化语句。
让我们看看如何创建模式:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:mem:testdb;INIT=CREATE SCHEMA IF NOT EXISTS baeldung\\;SET SCHEMA baeldung;"/>
<property name="username" value="admin"/>
<property name="password" value="password"/>
</bean>
如前所见,URL中有多个初始化语句可能会使其难以阅读。因此,最好将它们放入单个SQL文件中,并在URL中引用该文件:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:mem:testdb;INIT=RUNSCRIPT FROM 'src/main/resources/h2init.sql';"/>
<property name="username" value="admin"/>
<property name="password" value="password"/>
</bean>
4. 总结
H2内存数据库是Java开发者常用的内存和嵌入式数据库选项之一。由于其速度快、占用资源少,非常适合用于软件测试和自动化管道等场景。
在这篇文章中,我们看到了几种确保在应用程序启动时我们的H2内存数据库自动初始化并准备好查询的方法。无论我们使用纯JDBC还是Spring框架,只需几行配置,我们就可以确保内存数据库在启动时完全初始化并可供使用。
如往常一样,上述代码示例可以在GitHub上找到。