Java H2 数据库详解
1. 简介
H2 是一个用 Java 编写的关系型数据库管理系统(RDBMS),它以微内核模式运行,具有高性能和嵌入式特性。相比其他流行的数据库,如 MySQL 和 PostgreSQL,H2 不使用磁盘上的文件,而是将所有数据存储在内存中,以提供更快的访问速度。本文将深入探讨 H2 数据库的各个方面,包括数据库的创建和连接、数据操作和查询、事务支持、索引和约束等。
2. 数据库的创建和连接
在使用 H2 数据库之前,首先需要创建一个数据库。H2 支持内存数据库和文件数据库两种类型。
2.1 创建内存数据库
创建内存数据库非常简单,只需指定数据库的 URL 即可:
import org.h2.Driver;
public class InMemoryDatabaseExample {
public static void main(String[] args) {
try {
Class.forName(Driver.class.getName());
Connection connection = DriverManager.getConnection("jdbc:h2:mem:test");
// 数据库连接成功
connection.close();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
}
上述代码使用 DriverManager
获取 H2 的连接,并指定数据库的 URL 为 jdbc:h2:mem:test
,表示在内存中创建一个名为 “test” 的数据库。创建成功后,可以通过 Connection
对象执行其他数据库操作。
2.2 创建文件数据库
创建文件数据库需要指定数据库文件的路径和名称。如果指定的数据库文件不存在,H2 将自动创建它;如果已存在,H2 将连接到现有的数据库。
import org.h2.Driver;
public class FileDatabaseExample {
public static void main(String[] args) {
try {
Class.forName(Driver.class.getName());
Connection connection = DriverManager.getConnection("jdbc:h2:file:/data/db/test");
// 数据库连接成功
connection.close();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
}
上述代码使用 DriverManager
获取 H2 的连接,并指定数据库的 URL 为 jdbc:h2:file:/data/db/test
,表示在 /data/db/
目录下创建一个名为 “test” 的数据库文件。创建成功后,可以通过 Connection
对象执行其他数据库操作。
3. 数据操作和查询
H2 数据库支持标准的 SQL 语法,可以进行数据的增删改查等操作。下面将介绍如何使用 Java 连接到 H2 数据库,并进行数据操作和查询。
import org.h2.Driver;
public class DataManipulationExample {
public static void main(String[] args) {
try {
Class.forName(Driver.class.getName());
Connection connection = DriverManager.getConnection("jdbc:h2:mem:test");
Statement statement = connection.createStatement();
// 创建表
String createTableSql = "CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255))";
statement.executeUpdate(createTableSql);
// 插入数据
String insertDataSql = "INSERT INTO users (id, name) VALUES (1, 'John'), (2, 'Jane')";
statement.executeUpdate(insertDataSql);
// 更新数据
String updateDataSql = "UPDATE users SET name = 'Tom' WHERE id = 1";
statement.executeUpdate(updateDataSql);
// 删除数据
String deleteDataSql = "DELETE FROM users WHERE id = 2";
statement.executeUpdate(deleteDataSql);
// 查询数据
String queryDataSql = "SELECT * FROM users";
ResultSet resultSet = statement.executeQuery(queryDataSql);
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
resultSet.close();
statement.close();
connection.close();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
}
上述代码使用 Statement
对象执行 SQL 语句,包括创建表、插入数据、更新数据和删除数据。同时,通过执行查询语句可以获取返回的结果集,并进行后续处理。上述代码执行后的结果为:
ID: 1, Name: Tom
4. 事务支持
H2 数据库支持事务,可以对一系列数据库操作进行分组和管理。在 Java 中,可以通过 Connection
对象的相关方法来开始、提交或回滚事务。
import org.h2.Driver;
public class TransactionExample {
public static void main(String[] args) {
try {
Class.forName(Driver.class.getName());
Connection connection = DriverManager.getConnection("jdbc:h2:mem:test");
connection.setAutoCommit(false); // 禁用自动提交
Statement statement = connection.createStatement();
// 插入数据
String insertDataSql = "INSERT INTO users (id, name) VALUES (1, 'John'), (2, 'Jane')";
statement.executeUpdate(insertDataSql);
// 删除数据
String deleteDataSql = "DELETE FROM users WHERE id = 2";
statement.executeUpdate(deleteDataSql);
connection.commit(); // 提交事务
connection.setAutoCommit(true); // 恢复自动提交
// 查询数据
String queryDataSql = "SELECT * FROM users";
ResultSet resultSet = statement.executeQuery(queryDataSql);
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
resultSet.close();
statement.close();
connection.close();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
}
上述代码使用 Connection
对象的 setAutoCommit(false)
方法来禁用自动提交,然后通过 commit()
方法手动提交事务。如果需要回滚事务,可以调用 rollback()
方法。在上述代码中,插入数据成功,但删除数据之后通过查询无法查到该数据。
5. 索引和约束
H2 数据库支持在表的列上创建索引和约束,以提高数据查询的效率,并保证数据的完整性和一致性。
5.1 创建索引
创建索引可以加速数据的查找和排序操作。H2 数据库支持创建唯一索引和普通索引。
import org.h2.Driver;
public class IndexExample {
public static void main(String[] args) {
try {
Class.forName(Driver.class.getName());
Connection connection = DriverManager.getConnection("jdbc:h2:mem:test");
Statement statement = connection.createStatement();
// 创建表
String createTableSql = "CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255))";
statement.executeUpdate(createTableSql);
// 创建普通索引
String createIndexSql = "CREATE INDEX idx_name ON users(name)";
statement.executeUpdate(createIndexSql);
// 查询数据
String queryDataSql = "SELECT * FROM users WHERE name = 'John'";
ResultSet resultSet = statement.executeQuery(queryDataSql);
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
resultSet.close();
statement.close();
connection.close();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
}
上述代码使用 CREATE INDEX
语句创建了一个普通索引,然后通过查询语句查找 name 为 “John” 的数据。