H2

作者: hemiao3000 | 来源:发表于2022-02-27 15:54 被阅读0次

隔离数据库环境

使用 H2 内存数据库提高数据库操作速度

spring-test 中使用 spring-tx 进行事务回滚,以保证测试代码的隔离之后,我们的测试环境还有一处可改进的地方:提高测试环境中数据库的执行速度。

单元测试必须快速执行。因为一个方法不仅会有一个 TestCase ,一个业务方法的背后,需要有大量的测试代码对其进行测试。理论上测试代码要远多于业务代码。所以,执行测试用例时,会有更频繁的数据库操作。

为了不让 MySQL 的磁盘操作影响到测试代码的执行,我们可以使用内存数据库。通过内存操作,以替代磁盘操作。

相较于它的竞争者而言,它最大的特点在于,它兼容 MySQL,虽然仍有些不完全一致的地方,但相较而言那都是些细枝末节,无关紧要之处。

它支持多种运行模式:将数据库数据存储于内存中( 内存运行模式 ),或存储于磁盘上。H2 数据库不需要专门的去启动/运行它,直接连接即可!

H2 是一个由 Java 代码实现的内嵌式数据库,它支持三种运行模式:

运行模式 说明
Embedded
嵌入式
无需配置本地(或远程)数据库 ;
数据库连接关闭时,数据与表结构依然存在;
In-Memory
内存模式
同上,区别:数据库连接关闭时,数据与表结构删除;
ServerMode
传统模式
需要配置本地(或远程)数据库;

pom.xml 引入:

<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <version>1.4.197</version> <!-- spring-boot-dependencies 中有版本号 -->
  <scope>test</scope> <!-- 由于我们仅用它来进行 JUnit 测试,
                           因此只在测试环境中使用它。
                           项目发布时,项目的包中不需要包含它 -->
</dependency>
  • 四大数据库连接属性

    String DRIVER = "org.h2.Driver";
    String URL = "jdbc:h2:mem:scott;MODE=MYSQL;DB_CLOSE_DELAY=-1";
    String USERNAME = "sa";
    String PASSWORD = "";
    
  • jdbc:h2:mem:scott

    这是数据库 URL 的核心部分,其中 mem 就表示使用内存模式的 H2。H2 的各种不同的使用/运行模式,主要体现在这个部分。

    此处指令连接 scott 数据库,h2 就会自动帮我们创建名为 scott 的 database,因此后续的 sql 语句中无须再指定创建 scott,也不用再使用 use scott 切换到它。

  • MODE=MYSQL

    H2 并不是唯一的嵌入式数据库,也不是唯一具有内存模式的嵌入式数据库,但是它是与 MySQL 语法最兼容的具有内存模式的嵌入式数据库,这也是 JUnit中 首选 H2 的原因。

  • DB_CLOSE_DELAY=-1

    默认情况下,H2 内存中的数据库是在最后一个连接断开后关闭数据库,即删除数据库及其中所有数据。

    设置为 -1 表示不以连接数作为判断标准,而是持续保持数据库的存在,直到程序运行结束。

  • 用户名和密码

    由于使用的是 h2 的内存模式,所以这里并不存在实际上的连接校验身份的功能。因此用户名密码并没有实际的作用。按惯例写成 "sa""" 既可。

spring-dao.xml 其实很简单,只需要修改数据库连接池的四大连接属性即可。

<!-- 数据库连接池  -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" 
        init-method="init" destroy-method="close">
    <property name="driverClassName" value="org.h2.Driver"/>
    <property name="url" value="jdbc:h2:mem:scott;MODE=MYSQL;DB_CLOSE_DELAY=-1"/>
    <property name="username" value="sa"/>
    <property name="password" value=""/>
</bean>

初始化数据库有 2 种方式: <jdbc:initialize-database> 配置文件配置,和 @Sql 注解配置。推荐使用 @Sql 注解配置。

@Slf4j
@SpringJUnitConfig(H2Config.class)
class DepartmentDaoTest {

    @Resource
    private DepartmentDao dao;

    @Test
    @Sql({ "/sql/department.sql"})
    void selectByPrimaryKey() {
        assertNotNull(dao);
        System.out.println(dao.selectByPrimaryKey(1L));
    }
}

h2 与 mysql 的语法区别:

  1. h2 不支持 engine 关键字;
  2. h2 不支持以 alter table add constraint 的方式为表添加外键
  3. h2 的 insert sql 语句只支持标准的 values 关键字,mysql 还额外支持 value 。

其它区别还有待于发掘。

相关文章

网友评论

      本文标题:H2

      本文链接:https://www.haomeiwen.com/subject/bguhrrtx.html