我希望在Java + DBUnit /.
中的每次测试后重置数据库AND序列我已经看过这个问题,但没有我正在努力获得的代码解决方案。 How to use Oracle Sequence Numbers in DBUnit?
答案 0 :(得分:13)
我找到了答案,它出现在Official Documentation。它就像您用于准备数据库的数据集一样简单,添加 reset_sequences 属性以及要重置的列表。
<?xml version='1.0' encoding='UTF-8'?>
<dataset reset_sequences="emp_seq, dept_seq">
<emp empno="1" ename="Scott" deptno="10" job="project manager" />
....
</dataset>
此解决方案无法正常工作,因为它没有真正重置序列,只模拟插入行上的重置。如果要有效地重置它,则应执行一些命令。为此,我已经为此类扩展了DatabaseOperation。
public static final DatabaseOperation SEQUENCE_RESETTER_POSTGRES = new DatabaseOperation() {
@Override
public void execute(IDatabaseConnection connection, IDataSet dataSet)
throws DatabaseUnitException, SQLException {
String[] tables = dataSet.getTableNames();
Statement statement = connection.getConnection().createStatement();
for (String table : tables) {
int startWith = dataSet.getTable(table).getRowCount() + 1;
statement.execute("alter sequence " + table + "_PK_SEQ RESTART WITH "+ startWith);
}
}
};
public static final DatabaseOperation SEQUENCE_RESETTER_ORACLE = new DatabaseOperation() {
@Override
public void execute(IDatabaseConnection connection, IDataSet dataSet)
throws DatabaseUnitException, SQLException {
String[] tables = dataSet.getTableNames();
Statement statement = connection.getConnection().createStatement();
for (String table : tables) {
int startWith = dataSet.getTable(table).getRowCount() + 1;
statement.execute("drop sequence " + table + "_PK_SEQ if exists");
statement.execute("create sequence " + table + "_PK_SEQ START WITH " + startWith);
}
}
};
答案 1 :(得分:4)
我已经测试了@Chexpir提供的解决方案,这里有一个改进/更清晰的方法(PostgreSQL实现) - 还要注意序列重置为1(而不是检索行数)
public class ResetSequenceOperationDecorator extends DatabaseOperation {
private DatabaseOperation decoree;
public ResetSequenceOperationDecorator(DatabaseOperation decoree) {
this.decoree = decoree;
}
@Override
public void execute(IDatabaseConnection connection, IDataSet dataSet) throws DatabaseUnitException, SQLException {
String[] tables = dataSet.getTableNames();
Statement statement = connection.getConnection().createStatement();
for (String table : tables) {
try {
statement.execute("ALTER SEQUENCE " + table + "_id_seq RESTART WITH 1");
}
// Don't care because the sequence does not appear to exist (but catch it silently)
catch(SQLException ex) {
}
}
decoree.execute(connection, dataSet);
}
}
在您的DatabaseTestCase中:
public abstract class AbstractDBTestCase extends DataSourceBasedDBTestCase {
@Override
protected DatabaseOperation getTearDownOperation() throws Exception {
return new ResetSequenceOperationDecorator(DatabaseOperation.DELETE_ALL);
}
}
答案 2 :(得分:0)
如果对您有所帮助,请查看以下链接。
How to revert the database back to the initial state using dbUnit?