【发布时间】:2010-11-18 18:18:15
【问题描述】:
使用 hibernate/hql 截断表的推荐方法是什么?
我试过了:
查询查询 = session.createQuery("截断表 MyTable"); 查询.executeUpdate();但它不起作用(截断似乎没有记录在 hql 的任何地方......)
【问题讨论】:
-
截断不是标准的DML或DDL命令,所以不支持是正常的。
使用 hibernate/hql 截断表的推荐方法是什么?
我试过了:
查询查询 = session.createQuery("截断表 MyTable"); 查询.executeUpdate();但它不起作用(截断似乎没有记录在 hql 的任何地方......)
【问题讨论】:
您可以改用session.createSQLQuery():
session.createSQLQuery("truncate table MyTable").executeUpdate();
不用说,这在便携性方面并不理想。在映射中定义此查询并在代码中将其检索为命名查询可能是一个好主意。
【讨论】:
createNativeQuery是5.2以后的首选
小心,truncate 和 delete 是完全独立的 sql 语句:
如果你把它们放在一起:
所以要小心你真正想要使用的语句。
关于如何用 hql 截断表,应该禁止从应用程序运行 DDL(截断、创建表、删除表等)。你应该使用删除。但是如果表很大,它也不会工作。 这就是为什么在应用程序中清空表通常是个坏主意。 如果你想做一些清理工作,通常最好每晚在 sql 脚本中运行一次 truncate。
请注意,我不知道您的应用程序的细节,它只是笼统地说。
【讨论】:
我想一种可怕的做法是删除所有内容。
public int hqlTruncate(String myTable){
String hql = String.format("delete from %s",myTable);
Query query = session.createQuery(hql);
return query.executeUpdate();
}
【讨论】:
我在 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);
【讨论】:
你可以这样做:
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());
}
});
}
【讨论】: