【问题标题】:Calling a DB function from Hibernate从 Hibernate 调用数据库函数
【发布时间】:2013-06-03 17:34:44
【问题描述】:

我正在尝试创建一个每周五重新索引我们的数据库的工作。我们正在使用休眠,到目前为止我尝试过的一切都失败了。有没有办法使用休眠执行 SQL 管理命令?如:

    Session session = helper.getSession();
    session.createQuery("DBCCREINDEX(User)").executeUpdate();

或者有没有更好的方法在 Hibernate 中重新索引?

【问题讨论】:

    标签: java sql hibernate indexing hql


    【解决方案1】:

    下面引用的示例适用于 Oracle PL/SQL,但在概念上它与其他数据库相同。通过“构建作业”和“执行 SQL 管理命令”,我假设您将在需要调用的数据库中存储某种函数。

    https://stackoverflow.com/a/2943733/131929 有一个冗长的解释,但归结为

    CallableStatement statement = session.connection().prepareCall(
            "{ ? = call name_of_your_function(?) }");
    

    允许您直接使用ConnectionPreparedStatement/CallableStatement

    https://stackoverflow.com/a/1703398/131929 本质上是相同的,但它使用了Session#doWork

    session.doWork(new Work() {
      public void execute(Connection connection) throws SQLException {
        CallableStatement call = connection.prepareCall("{ ? = call name_of_your_function(?) }");
    

    请注意,在这两个示例中,都需要在 Java 代码中处理函数的返回值,您可能会也可能不会。

    【讨论】:

    • 我们最终按照这些思路做了一些事情。
    • 像我提供的解决方案一样,使用 CallableStatement 和仅使用 PreparedStatement 有区别吗? (还有一个正确的吗?)
    • “我们最终按照这些思路做了一些事情” - 哦,真的吗?如果您至少支持(如果不接受)这个答案,那就太好了。事实上,在示例中使用CallableStatement 可能(真的不知道)比您的解决方案更“正确”,因为CallableStatement 旨在用于调用存储过程/函数。试试谷歌的“CallableStatement vs. PreparedStatement”,例如this,这里没有足够的空间容纳更多。
    【解决方案2】:

    Session.createQuery() 需要 HQL 查询。如果要执行 SQL,请使用Session.createSQLQuery()

    【讨论】:

    • 我们最终尝试了这个,我相信问题在于我们调用了一个没有返回任何内容的存储过程。 createSQLQuery() 使用返回结果集的方法,但我们的查询没有返回任何内容(只是执行了一个操作...重新索引)。所以我们的实现是不正确的。不过,感谢您的回答。
    【解决方案3】:

    在出现许多错误后,我们最终以自己的方式解决了以下问题。准备好的语句是在 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();
            }
        });
    }
    

    这似乎已经给出了预期的结果并执行了......但是我们现在只需要解决超时问题。

    【讨论】:

    • “立即解决超时问题” - 是的,我可以想象。如果被调用的过程需要“很长时间”(无论这意味着什么)来完成,您需要在语句上使用 setQueryTimeout 并在其自己的工作线程中运行整个过程。
    【解决方案4】:

    试试这个代码 -

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

    【讨论】:

      猜你喜欢
      • 2010-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-18
      • 2019-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多