使用 hibernate/hql 截断表的推荐方法是什么?
我试过这个:
查询查询 = session.createQuery("截断表 MyTable"); 查询.executeUpdate();
但它没有用(截断似乎没有记录在 hql 的任何地方......)
您可以session.createSQLQuery()
改用:
session.createSQLQuery("truncate table MyTable").executeUpdate();
不用说,这在便携性方面并不理想。在映射中定义此查询并在代码中将其检索为命名查询可能是一个好主意。
小心,截断和删除是完全独立的 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());
}
});
}