Использование hibernate/hql для усечения таблицы?
Каков рекомендуемый способ обрезания таблицы с помощью hibernate/hql?
Я пробовал это:
Query query = session.createQuery("truncate table MyTable");
query.executeUpdate();
Но это не сработало (truncate, похоже, не документируется нигде в hql...)
Ответы
Ответ 1
Я предполагаю, что ужасный способ сделать это будет удалять все.
public int hqlTruncate(String myTable){
String hql = String.format("delete from %s",myTable);
Query query = session.createQuery(hql);
return query.executeUpdate();
}
Ответ 2
Вместо этого вы можете использовать session.createSQLQuery()
:
session.createSQLQuery("truncate table MyTable").executeUpdate();
Излишне говорить, что это не идеально с точки зрения переносимости. Вероятно, это хорошая идея, чтобы определить этот запрос при сопоставлении и получить его в коде как именованный запрос.
Ответ 3
Будьте осторожны, усечение и удаление - это совершенно отдельные операторы SQL:
- удаление - это DML, а усечение - это DDL, что означает, что удаление можно откатить, а усечение нельзя откатить
- Удалить должен найти каждую строку один за другим. усечение происходит мгновенно
- удаление использует журналы отмены, а усечение не
Если сложить все вместе:
- если вы хотите, чтобы он был откатным, вы не хотите использовать усечение
- если вы используете delete, учитывая размер таблицы, которую вы хотите очистить:
- если таблица маленькая, вы не увидите никакой разницы
- если таблица среднего размера, вы столкнетесь с плохой производительностью
- если таблица большая, вам не хватит места в табличном пространстве отмены, и вы не сможете ничего очистить
так что будьте осторожны с тем, какое утверждение вы действительно хотите использовать.
Что касается усечения таблицы с помощью hql, следует запретить запуск DDL (усечение, создание таблицы, удаление таблицы и т.д.) Из приложения и из него. Вы должны использовать удалить. Но если стол большой, он тоже не будет работать.
Поэтому очистка таблицы в приложении - вообще плохая идея.
Если вы хотите выполнить некоторую очистку, часто лучше запускать truncate внутри сценария sql один раз каждую ночь.
Обратите внимание, что я не знаю специфику вашего приложения и что оно говорит только в целом.
Ответ 4
Я использовал синтаксис delete в HQL для поддержки переносимости. Отлично работает:
public abstract class GenericDAOImpl<T, ID extends Serializable> implements GenericDAO<T, ID> {
private Class<T> persistentClass;
// Balance of dao methods snipped... :)
/**
* Clears all records from the targetted file.
* @throws DAOException
*/
public int truncate() throws DAOException {
Session s = getSession();
int rowsAffected = 0;
try {
Class c = getPersistentClass();
String hql = "delete from " + c.getSimpleName();
Query q = s.createQuery( hql );
rowsAffected = q.executeUpdate();
} catch ( HibernateException e ) {
throw new DAOException( "Unable to truncate the targetted file.", e );
}
return rowsAffected;
}
/**
* Returns a Class object that matches target Entity.
*
* @return Class object from constructor
*/
public Class<T> getPersistentClass() {
return persistentClass;
}
Работает отлично и полностью усекает целевую таблицу. Следует использовать с осторожностью, так как ваш сервер db будет выполнять это утверждение с большой эффективностью...:)
Ответ 5
Предотвращение SQL-инъекций вы можете использовать:
String escapedSQL = StringEscapeUtils.escapeSql(unescapedSQL);
от Apache Commons-Lang
метод StringEscapeUtils.escapeSql