我正在一个演示服务器中设置我的应用程序的新版本,并希望找到一种每天重置数据库的方法.我想我总是可以执行一个cron作业执行drop并创建查询,但我正在寻找一种更清洁的方法.我尝试使用具有drop-create方法的特殊持久性单元,但它不起作用,因为系统经常连接和断开服务器(按需).
有更好的方法吗?
Tho*_*ler 73
H2支持一个特殊的SQL语句来删除所有对象:
DROP ALL OBJECTS [DELETE FILES]
Run Code Online (Sandbox Code Playgroud)
如果您不想删除所有表,则可能需要使用truncate table:
TRUNCATE TABLE
Run Code Online (Sandbox Code Playgroud)
Nil*_*aud 20
由于此响应是"重置H2数据库"的第一个Google结果,我在下面发布了我的解决方案:
在每个JUnit @tests之后:
重新启用约束.
@After
public void tearDown() {
try {
clearDatabase();
} catch (Exception e) {
Fail.fail(e.getMessage());
}
}
public void clearDatabase() throws SQLException {
Connection c = datasource.getConnection();
Statement s = c.createStatement();
// Disable FK
s.execute("SET REFERENTIAL_INTEGRITY FALSE");
// Find all tables and truncate them
Set<String> tables = new HashSet<String>();
ResultSet rs = s.executeQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='PUBLIC'");
while (rs.next()) {
tables.add(rs.getString(1));
}
rs.close();
for (String table : tables) {
s.executeUpdate("TRUNCATE TABLE " + table);
}
// Idem for sequences
Set<String> sequences = new HashSet<String>();
rs = s.executeQuery("SELECT SEQUENCE_NAME FROM INFORMATION_SCHEMA.SEQUENCES WHERE SEQUENCE_SCHEMA='PUBLIC'");
while (rs.next()) {
sequences.add(rs.getString(1));
}
rs.close();
for (String seq : sequences) {
s.executeUpdate("ALTER SEQUENCE " + seq + " RESTART WITH 1");
}
// Enable FK
s.execute("SET REFERENTIAL_INTEGRITY TRUE");
s.close();
c.close();
}
Run Code Online (Sandbox Code Playgroud)另一种解决方案是在每次测试开始时重新创建数据库.但是对于大数据库来说,这可能太长了.
Spring 中有特殊的语法用于单元测试中的数据库操作
@Sql(scripts = "classpath:drop_all.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
@Sql(scripts = {"classpath:create.sql", "classpath:init.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
public class UnitTest {}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我们在每个测试方法之后执行drop_all.sql脚本(我们删除所有需要的表)。在这个例子中,我们执行create.sql脚本(我们在其中创建所有必需的表)和init.sql脚本(我们在每个测试方法之前初始化所有必需的表)。