H2 内存模式

H2 内存模式是 H2 数据库提供的一种特殊运行模式。

在 H2 内存模式下,数据库将所有的数据存储在内存(RAM)中,而不是像传统数据库那样存储在磁盘上。这意味着数据的读写操作直接在内存中进行,无需进行磁盘 I/O 操作。例如,当执行一条 SQL 查询语句来检索数据时,数据直接从内存中的数据结构中获取,而不是从磁盘文件中读取。

由于数据存储在内存中,这种模式下的数据库具有临时性。一旦数据库连接关闭或者应用程序终止,内存中的数据将会丢失。这是因为内存是易失性存储介质,当与之相关的进程结束时,其所占用的内存空间会被释放。

连接字符串

典型的用于连接 H2 内存模式数据库的连接字符串格式为:

jdbc:h2:mem: [databaseName]

其中:

  • jdbc  表示这是一个 Java 数据库连接(JDBC)的连接字符串;

  • h2  指定了要连接的数据库为 H2 数据库;

  • mem  表明是内存模式;

  • [databaseName]  是数据库的名称,可以自行指定,例如 jdbc:h2:mem:test 中的 test 就是数据库名称。

除了上述标准字段外,还可以在连接字符串中添加一些参数来调整数据库的行为。例如,DB_CLOSE_DELAY=-1 可以添加到连接字符串中,如 jdbc:h2:mem:test;DB_CLOSE_DELAY=-1。这个参数的作用是在最后一个连接关闭后,不立即关闭数据库。在默认情况下(没有这个参数或者参数值为 0 时),当最后一个连接关闭时,内存数据库会立即关闭,导致数据丢失。但设置 DB_CLOSE_DELAY=-1后,数据库在连接关闭后仍会保留一段时间,这在某些测试场景下非常有用,例如在测试用例之间需要共享数据库状态时。

适用场景

单元测试

在进行 Java 单元测试时,经常需要创建一个临时的数据库环境来测试数据库相关的代码逻辑。H2 内存模式非常适合这种场景,因为它可以快速创建和销毁数据库实例,而且不会对磁盘上的文件系统造成任何持久化的影响。例如,在测试一个数据访问层(DAO)类时,可以使用 H2 内存模式数据库来模拟真实的数据库操作,如插入、查询、更新和删除数据等操作,确保 DAO 类的方法在各种情况下都能正确工作。

快速原型开发

当开发人员在项目的早期阶段进行快速原型开发时,可能需要一个简单、快速的数据库解决方案来验证业务逻辑和数据处理流程。H2 内存模式的快速读写特性使得它成为一个理想的选择。开发人员可以快速地在内存中创建数据库结构,插入一些测试数据,然后进行业务逻辑的开发和验证,而不必担心数据库的复杂配置和持久化存储问题。

临时数据缓存

对于一些只在程序运行期间需要临时存储的数据,H2 内存模式也可以作为一种有效的数据缓存解决方案。例如,在一个复杂的计算任务中,某些中间结果只需要在当前计算过程中使用,不需要持久化到磁盘上。可以将这些中间结果存储在 H2 内存模式数据库中,以便在后续的计算步骤中快速访问,提高计算效率。

简单示例

使用 JDBC 连接到 H2 内存数据库,然后创建 person 数据表,以及插入数据、查询数据操作,如下:

package com.hxstrive.h2.memory_database;

import java.sql.*;

/**
 * H2内存数据库示例
 * @author hxstrive.com
 * @since 1.0.0  2024/2/18 15:18
 **/
public class H2MemoryDatabaseExample {
    private static final String DB_DRIVER = "org.h2.Driver";
    private static final String DB_CONNECTION = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1";
    private static final String DB_USER = "sa";
    private static final String DB_PASSWORD = "";

    public static void main(String[] args) throws Exception {
        Connection connection = null;
        PreparedStatement createPs = null;
        PreparedStatement insertPs = null;
        PreparedStatement selectPs = null;

        try {
            // 获取连接
            Class.forName(DB_DRIVER);
            connection = DriverManager.getConnection(DB_CONNECTION, DB_USER, DB_PASSWORD);

            // 设置不自动提交
            connection.setAutoCommit(false);

            // 创建数据表
            createPs = connection.prepareStatement("CREATE TABLE PERSON(id int primary key, name varchar(255))");
            createPs.executeUpdate();

            // 插入数据
            insertPs = connection.prepareStatement("INSERT INTO PERSON(`id`, `name`) values (?,?)");
            insertPs.setInt(1, 1);
            insertPs.setString(2, "Jose");
            insertPs.executeUpdate();

            // 查询数据
            selectPs = connection.prepareStatement("select * from PERSON");
            ResultSet rs = selectPs.executeQuery();
            while (rs.next()) {
                System.out.println("Id=" + rs.getInt("id") + "  Name=" + rs.getString("name"));
            }

            // 提交事务
            connection.commit();
        } catch (Exception e) {
            e.printStackTrace();
            // 回滚事务
            if(null != connection) {
                connection.rollback();
            }
        } finally {
            // 释放资源
            if(null != selectPs) {
                selectPs.close();
            }

            if(null != insertPs) {
                insertPs.close();
            }

            if(null != createPs) {
                createPs.close();
            }

            if(null != connection) {
                connection.close();
            }
        }
    }

}

运行示例,输出如下:

Id=1  Name=Hello World

连接地址“jdbc:h2:mem:test;DB_CLOSE_DELAY=-1”说明:

  • jdbc - 这是 Java Database Connectivity(Java 数据库连接)的缩写,它是 Java 语言中用于执行 SQL 语句与数据库进行交互的 API 规范。Java 程序通过 JDBC 来连接各种不同的数据库,如 MySQL、Oracle、H2 等。

  • h2 - 表示要连接的数据库是 H2 数据库。

  • mem:test -“mem” 表示内存模式。在这种模式下,H2 数据库将数据存储在内存中,而不是磁盘上。这使得数据库的操作速度非常快,适合用于单元测试等场景。当数据库运行在内存模式时,一旦应用程序关闭或者数据库连接关闭,数据库中的数据将会丢失。“test”是数据库的名称,你可以根据需要将其替换为其他名称,用于标识这个特定的内存数据库实例。

  • DB_CLOSE_DELAY=-1 - 在 H2 数据库中,这个参数用于控制数据库关闭的延迟时间。当设置为 - 1 时,表示在最后一个连接关闭后,不立即关闭数据库。在内存模式下,如果没有这个参数或者设置为其他值(例如默认值为 0,表示在最后一个连接关闭时立即关闭数据库),一旦连接关闭,数据库中的所有数据都会丢失。通过设置 DB_CLOSE_DELAY = - 1,可以在连接关闭后仍然保留数据库中的数据,这对于一些测试场景非常有用,例如在测试用例之间需要共享数据库状态时,可以确保数据不会因为连接的关闭而丢失。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号