与内存数据库中的同一个 H2 建立多个连接[重复]
Posted
技术标签:
【中文标题】与内存数据库中的同一个 H2 建立多个连接[重复]【英文标题】:Make multiple connections to same H2 In memory Database [duplicate] 【发布时间】:2018-09-29 23:55:43 【问题描述】:我经常遇到同样的问题:我想使用内存数据库对我的 DAO 执行单元测试。我正在使用 H2,但我相信问题与 HSQLDB 几乎相同。我的单元测试涉及三个步骤:
创建数据库并设置数据库架构(例如使用 SQL 脚本) 在数据库中插入测试所需的数据(例如:使用 DbUnit) 进行实际测试在非常简单的情况下,可以在所有三个步骤中使用相同的连接,但是一旦事情变得有点复杂(例如,使用框架查询数据库而不是直接使用 PreparedStatements 时),每个步骤需要一个连接。
问题:数据库似乎在连接关闭后立即被删除。如何解决?
【问题讨论】:
请注意,默认情况下,当连接关闭时,内存数据库将被丢弃。您可以覆盖此行为。请参阅:Keep H2 in-memory database between connections 和 H2 in-memory database. Table not found 【参考方案1】:关于这个话题,H2 documentation 给出了两个提示:
有时到同一个内存数据库的多个连接是 必需的。在这种情况下,数据库 URL 必须包含名称。例子:
jdbc:h2:mem:db1
。仅使用此 URL 访问同一数据库有效 在同一个虚拟机和类加载器环境中。默认情况下,关闭与数据库的最后一个连接会关闭 数据库。对于内存数据库,这意味着内容丢失。 要保持数据库打开,请将
;DB_CLOSE_DELAY=-1
添加到数据库 网址。保持内存数据库的内容只要 虚拟机还活着,使用jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
。
所以第一个解决方案是将;DB_CLOSE_DELAY=-1
添加到h2 url。但我对它有点不满意,因为它说数据库将永远留在内存中,而我希望它只在我的测试运行时才存在。
关于DB_CLOSE_DELAY 的文档提供了更多信息:
如果所有连接都关闭,则设置关闭数据库的延迟。值 -1 表示数据库永远不会关闭,直到关闭延迟设置为其他值或调用
SHUTDOWN
。值 0 表示无延迟(默认值;如果与数据库的最后一个连接已关闭,则数据库将关闭)。值 1 和更大的值表示关闭最后一个连接后数据库保持打开状态的秒数。
它提示其他解决方案,例如在关机前稍微延迟或手动调用SHUTDOWN
(我还没有找到如何在内存数据库上使用它)。
最后是我的整理方法:由于数据库在 last 连接关闭时关闭,我将只保持打开一个 blank 连接 从我创建的那一刻起数据库,直到我不再需要它为止。这种解决方法有点老套(让备用连接打开只是为了让数据库保持活动状态基本上是一种浪费),但它是迄今为止我找到的最优雅的解决方案。这是一个非常简化的抽象单元测试类的 sn-p 来说明这个解决方案:
import org.h2.jdbcx.JdbcDataSource;
public abstract class AbstractTestDao
private Connection blankConnection;
private DataSource dataSource;
protected DataSource getDataSource()
return dataSource;
@Before
public void setup() throws SQLException
JdbcDataSource jdbcDataSource = new JdbcDataSource();
jdbcDataSource.setUrl("jdbc:h2:mem:test");
this.dataSource = jdbcDataSource;
this.blankConnection = dataSource.getConnection();
@After
public void tearDown() throws SQLException
this.blankConnection.close();
儿童单元测试类将继承这一类并使用提供的 DataSource 对象来初始化用于查询数据库的库,以及执行问题中列出的其他两个步骤。测试完成后,空白连接关闭,内存数据库也关闭。
【讨论】:
以上是关于与内存数据库中的同一个 H2 建立多个连接[重复]的主要内容,如果未能解决你的问题,请参考以下文章