我为此编写了一个整合器。基本上,我们会在会话工厂创建流程中挂钩,迭代Hibernate找到的表映射,然后对每个表执行
TRUNCATE TABLE xxx
操作。由于我们无法截断带有外键约束的表,因此在截断操作之前禁用外键检查,然后重新启用。
static final class TruncatorIntegrator implements org.hibernate.integrator.spi.Integrator {
@Override
public void integrate(Metadata metadata,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
try (Session session = sessionFactory.openSession()) {
session.doWork(connection -> {
try (PreparedStatement preparedStatement = connection.prepareStatement("SET FOREIGN_KEY_CHECKS = 0;")) {
preparedStatement.executeUpdate();
System.out.printf("Disabled foreign key checks%n");
} catch (SQLException e) {
System.err.printf("Cannot disable foreign key checks: %s: %s%n", e, e.getCause());
}
metadata.collectTableMappings().forEach(table -> {
String tableName = table.getQuotedName();
try (PreparedStatement preparedStatement = connection.prepareStatement("TRUNCATE TABLE " + tableName)) {
preparedStatement.executeUpdate();
System.out.printf("Truncated table: %s%n", tableName);
} catch (SQLException e) {
System.err.printf("Couldn't truncate table %s: %s: %s%n", tableName, e, e.getCause());
}
});
try (PreparedStatement preparedStatement = connection.prepareStatement("SET FOREIGN_KEY_CHECKS = 1;")) {
preparedStatement.executeUpdate();
System.out.printf("Enabled foreign key checks%n");
} catch (SQLException e) {
System.err.printf("Cannot enable foreign key checks: %s: %s%n", e, e.getCause());
}
});
}
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
}
}
用法:我们必须在会话工厂创建流程中使用这个
Integrator
,并且每个测试都需要创建一个新的会话工厂。
BootstrapServiceRegistry bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder().applyIntegrator(new TruncatorIntegrator()).build();
StandardServiceRegistry registry = new StandardServiceRegistryBuilder(bootstrapServiceRegistry).build();
SessionFactory sessionFactory = new Configuration().buildSessionFactory(registry);