Подтвердить что ты не робот

Использование hibernate/hql для усечения таблицы?

Каков рекомендуемый способ обрезания таблицы с помощью hibernate/hql?

Я пробовал это:

 Query query = session.createQuery("truncate table MyTable");
 query.executeUpdate();

Но это не сработало (truncate, похоже, не документируется нигде в hql...)

4b9b3361

Ответ 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, что означает, что удаление можно откатить, а усечение нельзя откатить
  • Удалить должен найти каждую строку один за другим. усечение происходит мгновенно
  • удаление использует журналы отмены, а усечение не

Если сложить все вместе:

  1. если вы хотите, чтобы он был откатным, вы не хотите использовать усечение
  2. если вы используете 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