在DBUnit中重置序列?

时间:2013-12-16 09:47:09

标签: java dbunit

我希望在Java + DBUnit /.

中的每次测试后重置数据库AND序列

我已经看过这个问题,但没有我正在努力获得的代码解决方案。 How to use Oracle Sequence Numbers in DBUnit?

3 个答案:

答案 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?