web-dev-qa-db-ja.com

hibernate / hqlを使用してテーブルを切り捨てますか?

Hibernate/hqlを使用してテーブルを切り捨てる推奨される方法は何ですか?

私はこれを試しました:

クエリquery = session.createQuery( "truncate table MyTable"); 
 query.executeUpdate(); 

しかし、それは機能しませんでした(切り捨てはhqlのどこにも文書化されていないようです...)

19
user149100

それを行う恐ろしい方法は、すべてを削除することだと思います。

public int hqlTruncate(String myTable){
    String hql = String.format("delete from %s",myTable);
    Query query = session.createQuery(hql);
    return query.executeUpdate();
}
11
Tom

代わりにsession.createSQLQuery()を使用できます。

session.createSQLQuery("truncate table MyTable").executeUpdate();

言うまでもなく、これは移植性の観点から理想的ではありません。マッピングでこのクエリを定義し、名前付きクエリとしてコードで取得することをお勧めします。

38
ChssPly76

注意してください、切り捨てと削除は完全に別々のSQLステートメントです:

  • deleteはDMLであり、truncateはDDLです。つまり、deleteはロールバックでき、truncateはロールバックできません
  • deleteは、各行を1つずつ検索する必要があります。切り捨ては瞬時に行われます
  • 削除は元に戻すログを使用し、切り捨ては使用しません

あなたがそれをすべてまとめると:

  1. ロールバック可能にしたい場合は、切り捨てを使用したくない
  2. 削除を使用する場合、空にしたいテーブルのサイズを指定して:
    • テーブルが小さい場合は違いはありません
    • テーブルが中型の場合、パフォーマンスが低下します
    • テーブルが大きい場合、UNDO表領域のスペースが不足し、何も空にすることができなくなります

したがって、実際に使用するステートメントには注意してください。

Hqlを使用してテーブルを切り捨てる方法については、アプリケーションからDDL(切り捨て、テーブルの作成、テーブルの削除など)を実行することを禁止する必要があります。削除を使用する必要があります。しかし、テーブルが大きい場合も機能しません。そのため、アプリケーションでテーブルを空にすることは一般的に悪い考えです。クリーニングを実行する場合は、SQLスクリプト内で毎晩1回切り捨てを実行することをお勧めします。

私はあなたのアプリケーションの詳細を知らないことに注意してください、そしてそれは一般的に話しているだけです。

17
jeleb

移植性を維持するために、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;
}

うまく機能し、ターゲットテーブルを完全に切り捨てます。データベースサーバーがこのステートメントを非常に効率的に実行するため、注意して使用してください... :)

5
Piko

使用できるSQLインジェクションの防止:

String escapedSQL = StringEscapeUtils.escapeSql(unescapedSQL);

from Apache Commons-Lang

メソッド StringEscapeUtils.escapeSql

0
Andrzej Sydor