关闭准备好的语句

发布于 2024-11-23 22:04:29 字数 658 浏览 2 评论 0 原文

使用PreparedStatements 和ResultSets 是否会在每次使用时创建一个“新的数据库实例”? 或者,换句话说,如果我使用PreparedStatement和ResultSet,我应该在每次使用后或完成后关闭它们吗?

示例:

while (...){
        p = connection.prepareStatement(...);
        r = p.executeQuery();
        while (r.next()) {
        ....
        }
 }
 // We close at the end. Or there are any other p and r still opened...?
 p.close();
 r.close();

while (...){
        p = connection.prepareStatement(...);
        r = p.executeQuery();
        while (r.next()) {
        ....
        }
        p.close();
        r.close();
 }

注意:当然我会正确使用 try 和 close,这只是一个示例。

Does use of PreparedStatements and ResultSets creates a "new database instance" everytime they are used?
Or, whith other words, if I use a PreparedStatement and a ResultSet, should I close them after every use or once I finish?

Example:

while (...){
        p = connection.prepareStatement(...);
        r = p.executeQuery();
        while (r.next()) {
        ....
        }
 }
 // We close at the end. Or there are any other p and r still opened...?
 p.close();
 r.close();

OR

while (...){
        p = connection.prepareStatement(...);
        r = p.executeQuery();
        while (r.next()) {
        ....
        }
        p.close();
        r.close();
 }

NOTE: Of course I would use try and close properly, this is just an example.

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

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

发布评论

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

评论(2

甜心 2024-11-30 22:04:29

您应该关闭您打开的每一个。当您创建准备好的语句或结果集时,数据库会为它们分配资源,关闭它们会告诉数据库释放这些资源(数据库很可能最终会在超时后重新分配这些资源,但调用 close 让数据库知道它可以继续清理)。你的第二个例子更好,除了我会在准备好的语句之前关闭结果集。

因此,包含 try 块后,它看起来像:

while (...){
        PreparedStatement p = connection.prepareStatement(...);
        try {
          ResultSet r = p.executeQuery();
          try {
            while (r.next()) {
              ....
            }
          } finally {
            try {
              r.close();
            } catch (SQLException e) {
            // log this or something -- prevent these from masking original exception
            }
          }
        }
        finally {
          try {
            p.close();
          } catch (SQLException e) {
            // log this or something -- prevent these from masking original exception
          }
        }
 }

从关闭中捕获异常是丑陋的,但是如果在执行准备好的语句期间或在遍历结果集期间抛出异常,您需要确保看到它,而不是在关闭准备好的语句或结果集时抛出异常(这是由于某些网络故障造成的,无论如何你都无能为力)。

另请注意,使用 try-with-resources 是可行的,但如果您遇到数据库操作成功但调用 close 导致异常的情况,则会抛出异常。

我建议人们使用 spring-jdbc 库(它为您处理关闭所有内容),而不是手动生成不确定或冗长的 jdbc。

You should close every one you open. When you create a prepared statement or result set the database allocates resources for those, and closing them tells the database to free those resources (it's likely the database will reallocate these resources eventually after a timeout period, but calling close lets the database know it can go ahead and clean up). Your second example is better, except I'd close the result set before the prepared statement.

So with try blocks included it would look like:

while (...){
        PreparedStatement p = connection.prepareStatement(...);
        try {
          ResultSet r = p.executeQuery();
          try {
            while (r.next()) {
              ....
            }
          } finally {
            try {
              r.close();
            } catch (SQLException e) {
            // log this or something -- prevent these from masking original exception
            }
          }
        }
        finally {
          try {
            p.close();
          } catch (SQLException e) {
            // log this or something -- prevent these from masking original exception
          }
        }
 }

Catching the exceptions from the close is ugly, but if you have an exception thrown during execution of the prepared statement, or during traversal of the result set, you want to make sure that you see it, and not an exception thrown when closing the prepared statement or result set (which is due to some network glitch you can't do anything about anyway).

Also be aware that using try-with-resources will work, except that if you have a case where the database operation succeeds but calling close results in an exception then the exception will get thrown.

I recommend people use the spring-jdbc library (which handles closing everything for you) instead of cranking out iffy or verbose jdbc by hand.

二货你真萌 2024-11-30 22:04:29

第一种方法更好。

但是,您应该知道,如果您每次使用的 SQL 都相同,则可以重复使用准备好的语句(因此称为“准备”)。例如:

//Note: try/catch/finally blocks removed for brevity
p = connection.prepareStatement(...);
while (...){
    r = p.executeQuery();
    while (r.next()) {
        ....
    }
    r.close();
}
p.close();

The first way is better.

However, you should know that you can re-use prepared statements (hence the name "prepared") if the SQL you are using is the same each time. For example:

//Note: try/catch/finally blocks removed for brevity
p = connection.prepareStatement(...);
while (...){
    r = p.executeQuery();
    while (r.next()) {
        ....
    }
    r.close();
}
p.close();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文