h2 mysql 缓存_内存数据库:H2

本文介绍了如何在单元测试中使用H2内存数据库,包括配置URL、设置DB_CLOSE_DELAY以及与MySQL的语法兼容性。通过在JUnit测试中使用H2,可以快速隔离和执行数据库交互的代码,简化持久层测试。同时,文章指出H2在某些语法上与MySQL存在差异,如不支持表级Comment和多条Update语句等。
摘要由CSDN通过智能技术生成

测试持久层(Dao 层)的难点在于:

单元测试必须执行隔离的代码;而持久层的代码需要和数据库进行交互。

单元测试必须快速运行;而访问数据库却相对较慢。

以上两个难点决定了嵌入式数据库(H2、HSQLDB、Derby 和 Java DB)的使用价值。嵌入式数据库使用场景较少,但是是配合 JUnit 测试持久层的最佳选择。

1. 基本使用

在 pom.xml 中添加 h2 数据库的依赖。如果是在非 Maven 项目中使用,则下载该 h2 的 .jar 包并加入项目的 classpath 中。

com.h2database

h2

1.4.200

test

嵌入式数据库 H2 有多种使用模式,也可以将数据写入到磁盘上的文件中,但是大家更关注它的『内存模式』。即,将 database 和 table 建立在内存中。

private static final String DRIVER = "org.h2.Driver";

private static final String URL = "jdbc:h2:mem:scott;MODE=MYSQL;DB_CLOSE_DELAY=-1";

private static final String USERNAME = "sa";

private static final String PASSWORD = "";

jdbc:h2:mem:testdb

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

数据库名(以及后续的用户名和密码)并非重要部分,因为内存模式的数据库,在使用结束后会被清除,而且对它的使用无所谓用户名密码。

MODE=MYSQL

H2 并不是唯一的嵌入式数据库,也不是唯一具有内存模式的嵌入式数据库,但是它是与 MySQL 语法最兼容的具有内存模式的嵌入式数据库(虽然仍有些许特殊区别),这也是 JUnit中 首选 H2 的原因。

DB_CLOSE_DELAY=-1

默认情况下,H2 内存中的数据库是在最后一个(或指定个数)连接断开后关闭,这时就会删除数据库及其中数据。

设置为 -1 表示并非以连接数作为判断标准,而是持续保持数据库(即便没有连接),直到程序运行结束。

Class.forName(DRIVER);

Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);

Statement stmt = conn.createStatement();

stmt.execute( "...");

除了正常的使用获得数据库 Connection 对象之外,H2 自带了连接池功能。

JdbcConnectionPool cp = JdbcConnectionPool.create(URL, USERNAME, PASSWORD);

Connection conn = cp.getConnection();

2. 初始化数据库

虽然可以在 JUnit 的 Before 方法中通过执行 SQL 语句的方式在 @Test 之前去初始化数据库环境,但是 H2 有一个更好的特性能实现数据库的初始化操作:Execute SQL on connection 。

H2 支持在连接上数据库的时候就执行 SQL 语句,相当于就初始化了数据库环境:

jdbc:h2:mem:;...;INIT=RUNSCRIPT FROM '~/create.sql'

spring.datasource.url=jdbc:h2:mem:scott;MODE=MYSQL;DB_CLOSE_DELAY=-1;INIT=RUNSCRIPT FROM './src/test/resources/create.sql'

H2 internally uses Unicode, and supports all character encoding systems and character sets supported by the virtual machine you use.

可以为测试类编写父类,并实现 @Before 方法,以方便/确保于在每个 @Test 方法前执行统一的初始化数据库(初始化测试环境)的代码。

public class DaoTestBase {

private static final String DRIVER = "org.h2.Driver";

private static final String URL = "jdbc:h2:mem:testdb;MODE=MYSQL;DB_CLOSE_DELAY=-1";

private static final String USERNAME = "sa";

private static final String PASSWORD = "";

@Before

public void setUp() throws URISyntaxException, ClassNotFoundException, SQLException {

String sqlPathName = getClass().getResource("/conf/sql/xxx.sql" ).toURI().toString().substring(6);

Class.forName(DRIVER);

Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);

Statement stmt = conn.createStatement();

stmt.execute( "runscript from '" + sqlPathName + "'");

stmt.close();

conn.close();

}

}

三、H2 和 MySQL 的语法兼容性

所有的数据库都会有些小区别,即便是与 MySQL『最像』的数据库,H2 与 MySQL 仍有一些小区别:

不支持表级别的 Comment(注释)

插不支持入语句的出现'

H2 UNIQUE KEY是数据库级别的,而非表级别

无法执行多个 Update 语句,即一次 update 只能插入一条数据。

列别名无法用于子查询

不支持@:语法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值