使用 hibernate/hql 截断表?

发布于 2024-07-30 19:57:28 字数 198 浏览 3 评论 0原文

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

我已经尝试过这个:

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

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

What is the recommended way to truncate a table using hibernate/hql?

I've tried this:

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

But it didn't work (truncate doesn't seem do be documented anywhere in hql...)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

清晨说晚安 2024-08-06 19:57:29

注意,truncate 和delete 是完全独立的sql 语句:

  • delete 是DML,truncate 是DDL,这意味着delete 可以回滚,truncate 不能回滚
  • delete 必须一一找到每一行。 truncate 是瞬时
  • 删除使用撤消日志,而 truncate 则不会。

如果将它们全部放在一起:

  1. 您不想使用 truncate
  2. 如果您希望它可回滚,则如果您使用删除,则考虑到要清空的表的大小, :
    • 如果桌子很小,您将看不到任何差异
    • 如果表大小中等,您会遇到性能较差的情况
    • 如果表很大,您将耗尽撤消表空间中的空间,并且无法清空任何内容

,因此请注意您真正想要使用的语句。

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

请注意,我不知道您的应用程序的具体情况,它只是笼统地说。

Be careful, truncate and delete are totally separate sql statements :

  • delete is DML and truncate is DDL, which means that delete can be rollbacked and truncate cannot be rollbacked
  • delete has to find each row one by one. truncate is instantaneous
  • delete uses undo logs and truncate does not

If you put it all together :

  1. if you want it to be rollbackable, you don't want to use truncate
  2. if you use delete, given the size of the table you want to empty :
    • if the table is small you will see no difference
    • if the table is of medium size you will experience bad performance
    • if the table is large you will run out of space in the undo tablespace, and you won't be able to empty anything

so be careful of what statement you really want to use.

As to how truncating a table with hql, it should be forbidden to run DDL (truncate, create table, drop table, etc...) from and application. You should use delete. But if the table is large, it won't work, either.
That's why emptying a table in an application is in general a bad idea.
If you want to do some cleaning, it is often better to run truncate inside an sql script once each night.

Notice that I don't know the specifics of your application and that it is only talking in general.

无所的.畏惧 2024-08-06 19:57:29

我想一个可怕的方法就是删除所有内容。

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

I guess an horrible way of doing it would be deleting all.

public int hqlTruncate(String myTable){
    String hql = String.format("delete from %s",myTable);
    Query query = session.createQuery(hql);
    return query.executeUpdate();
}
小帐篷 2024-08-06 19:57:29

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

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

I used the delete syntax in an HQL to maintain portability. Works great:

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

Works great and totally truncates the targeted table. Use with caution as your db server will perform this statement with great efficiency... :)

驱逐舰岛风号 2024-08-06 19:57:29

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

String escapedSQL = StringEscapeUtils.escapeSql(unescapedSQL);

来自 Apache Commons-Lang

方法 StringEscapeUtils.escapeSql

Preventing SQL Injection you can use:

String escapedSQL = StringEscapeUtils.escapeSql(unescapedSQL);

from Apache Commons-Lang

method StringEscapeUtils.escapeSql

忆悲凉 2024-08-06 19:57:29

你可以这样做:

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

You can do it in this way:

    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());
            }
        });
    }
我们的影子 2024-08-06 19:57:28

您可以使用 session.createSQLQuery() 来代替:

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

不用说,这在可移植性方面并不理想。 在映射中定义此查询并在代码中将其检索为命名查询可能是个好主意。

You can use session.createSQLQuery() instead:

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

Needless to say, this is not ideal in terms of portability. It's probably a good idea to define this query in mapping and retrieve it in code as named query.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文