使用hibernate / hql截断表?

时间:2009-08-11 20:27:55

标签: hibernate hql truncate

使用hibernate / hql截断表的推荐方法是什么?

我试过这个:

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

但它没有用(截断似乎没有记录在hql的任何地方......)

6 个答案:

答案 0 :(得分:37)

您可以改为使用session.createSQLQuery()

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

毋庸置疑,这在便携性方面并不理想。在映射中定义此查询并在代码中将其作为命名查询进行检索可能是个好主意。

答案 1 :(得分:16)

小心,截断和删除是完全独立的sql语句: - delete是DML,truncate是DDL,这意味着可以回滚删除并且 truncate不能回滚 - 删除必须逐个查找每一行。截断是瞬间的 - delete使用撤消日志而截断不使用

如果你把它们放在一起: 1 /如果你想让它可以回滚,你不想使用truncate 2 /如果你使用删除,给定你要清空的表的大小:     - 如果桌子很小,你会看到没有区别     - 如果桌子中等大小,您将遇到不良表现     - 如果表很大,则撤消表空间中的空间不足,您将无法清空任何内容

所以要小心你真正想要使用的是什么声明。

关于如何用hql截断表,应该禁止从应用程序运行DDL(truncate,create table,drop table等)。你应该使用删除。但如果表格很大,它也不会起作用。 这就是为什么清空应用程序中的表通常是一个坏主意。 如果你想做一些清理,通常最好每晚在sql脚本中运行一次截断。

请注意,我不知道您的申请的细节,而且只是在谈论

答案 2 :(得分:11)

我想一个可怕的做法就是删除所有。

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

答案 3 :(得分:5)

我在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;
}

效果很好,完全截断目标表。请谨慎使用,因为您的数据库服务器将高效地执行此语句......:)

答案 4 :(得分:0)

防止SQL注入,您可以使用:

String escapedSQL = StringEscapeUtils.escapeSql(unescapedSQL);

来自Apache Commons-Lang

方法StringEscapeUtils.escapeSql

答案 5 :(得分:0)

您可以通过以下方式做到这一点:

    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());
            }
        });
    }