Java 从Hibernate调用DB函数
我试图建立一个工作,每周五重新索引我们的数据库。我们正在使用hibernate,到目前为止我所尝试的一切都失败了。有没有办法使用hibernate执行SQL管理命令?例如:Java 从Hibernate调用DB函数,java,sql,hibernate,indexing,hql,Java,Sql,Hibernate,Indexing,Hql,我试图建立一个工作,每周五重新索引我们的数据库。我们正在使用hibernate,到目前为止我所尝试的一切都失败了。有没有办法使用hibernate执行SQL管理命令?例如: Session session = helper.getSession(); session.createQuery("DBCCREINDEX(User)").executeUpdate(); 或者有更好的方法在Hibernate中重新编制索引吗?Session.createQuery()需要HQL查询。如
Session session = helper.getSession();
session.createQuery("DBCCREINDEX(User)").executeUpdate();
或者有更好的方法在Hibernate中重新编制索引吗?
Session.createQuery()
需要HQL查询。如果要执行SQL,请使用。下面引用的示例适用于Oracle PL/SQL,但从概念上讲,其他数据库也是如此。通过“构建作业”和“执行SQL管理命令”,我假设您将在数据库中存储某种需要调用的函数
有一个冗长的解释,但它归结为
CallableStatement statement = session.connection().prepareCall(
"{ ? = call name_of_your_function(?) }");
它允许您直接使用连接
和PreparedStatement
/CallableStatement
本质上是相同的,但它使用了会话#doWork
session.doWork(new Work() {
public void execute(Connection connection) throws SQLException {
CallableStatement call = connection.prepareCall("{ ? = call name_of_your_function(?) }");
请注意,在这两个示例中,都需要在Java代码中处理函数的返回值,这可能是您的情况,也可能不是您的情况。在出现许多错误后,我们最终找到了下面的解决方案。prepared语句是在MSSQL SSMS中重新创建索引的存储过程
private void reindex() {
Session session = helper.getSession();
PreparedStatement ps;
session.doWork(new Work() {
public void execute(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement("reindexTable");
ps.execute();
}
});
}
这似乎给出了所需的结果并执行了…但是我们现在只需要解决超时问题。试试这段代码-
private void reindex() {
Session session = helper.getSession();
PreparedStatement ps;
session.doWork(new Work() {
public void execute(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement("reindexTable");
ps.execute();
}
});
}
我们最终按照这些思路做了一些事情。使用CallableStatement和像我提供的解决方案那样使用PreparedStatement有什么区别吗?(还有一个正确吗?)“我们最终做了一些类似的事情”-哦,真的吗?如果你至少对这个答案投了赞成票,如果你不接受的话,那就太好了。事实上,使用示例中的
CallableStatement
可能(真的不知道)比您的解决方案更“正确”,因为CallableStatement
用于调用存储过程/函数。尝试Google的“CallableStatement vs.PreparedStatement”,例如,这里没有足够的空间容纳更多内容。我们最终尝试了这个方法,我相信问题在于我们调用的存储过程没有返回任何内容。createSQLQuery()使用一个返回resultSet的方法,但我们的查询没有返回任何内容(只执行一个操作…重新索引)。所以这对于我们的实现是不正确的。不过,谢谢你的回答。“现在解决超时问题”-是的,我可以想象。如果被调用的过程需要“long”(不管这意味着什么)才能完成,那么您需要对语句使用setQueryTimeout
,并在其自己的工作线程中运行整个过程。