Каков рекомендуемый способ усечения таблицы с помощью hibernate/hql?
Я пробовал это:
Query query = session.createQuery("truncate table MyTable"); query.executeUpdate();
Но это не сработало (усечение, похоже, нигде не задокументировано в hql...)
Каков рекомендуемый способ усечения таблицы с помощью hibernate/hql?
Я пробовал это:
Query query = session.createQuery("truncate table MyTable"); query.executeUpdate();
Но это не сработало (усечение, похоже, нигде не задокументировано в hql...)
Я предполагаю, что ужасным способом сделать это было бы удаление всего.
public int hqlTruncate(String myTable){
String hql = String.format("delete from %s",myTable);
Query query = session.createQuery(hql);
return query.executeUpdate();
}
Вместо этого вы можете использовать session.createSQLQuery()
:
session.createSQLQuery("truncate table MyTable").executeUpdate();
Излишне говорить, что это не идеально с точки зрения портативности. Вероятно, было бы неплохо определить этот запрос в сопоставлении и получить его в коде как именованный запрос.
createNativeQuery
предпочтительнее после версии 5.2.
- person aristotll; 08.09.2017
Будьте осторожны, усечение и удаление - это совершенно разные операторы sql:
Если собрать все вместе:
поэтому будьте осторожны с тем, какое утверждение вы действительно хотите использовать.
Что касается усечения таблицы с помощью hql, следует запретить запуск DDL (усечение, создание таблицы, удаление таблицы и т. д.) из приложения. Вы должны использовать удаление. Но если таблица большая, это тоже не сработает. Вот почему очистка таблицы в приложении — вообще плохая идея. Если вы хотите сделать некоторую очистку, часто лучше запускать truncate внутри скрипта sql один раз каждую ночь.
Обратите внимание, что я не знаю специфики вашего приложения и что оно говорит только в общих чертах.
Я использовал синтаксис удаления в 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;
}
Отлично работает и полностью обрезает целевую таблицу. Используйте с осторожностью, так как ваш сервер БД будет выполнять эту инструкцию с большой эффективностью... :)
Для предотвращения SQL-инъекций вы можете использовать:
String escapedSQL = StringEscapeUtils.escapeSql(unescapedSQL);
метод StringEscapeUtils.escapeSql
Вы можете сделать это следующим образом:
try (Session session = sessionFactory.openSession()) {
session.doWork(connection -> {
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());
}
});
}