Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中执行SQL时处理所有异常_Java_Sql - Fatal编程技术网

在Java中执行SQL时处理所有异常

在Java中执行SQL时处理所有异常,java,sql,Java,Sql,在Java中执行一条SQL语句涉及许多步骤: 创建连接 创建语句 执行语句,创建结果集 关闭结果集 结束语 密切联系 在每个步骤中,都可以抛出SQLException。如果我们希望正确地处理所有异常并释放所有资源,那么代码将如下所示,其中4个级别的TRY堆叠在彼此的顶部 try { Connection connection = dataSource.getConnection(); try { PreparedStatement statement =

在Java中执行一条SQL语句涉及许多步骤:

  • 创建连接
  • 创建语句
  • 执行语句,创建结果集
  • 关闭结果集
  • 结束语
  • 密切联系
  • 在每个步骤中,都可以抛出SQLException。如果我们希望正确地处理所有异常并释放所有资源,那么代码将如下所示,其中4个级别的TRY堆叠在彼此的顶部

    try {
         Connection connection = dataSource.getConnection();
         try {
               PreparedStatement statement = connection.prepareStatement("SELECT 1 FROM myTable");
               try {
                    ResultSet result = statement.executeQuery();
                    try {
                         if (result.next()) {
                               Integer theOne = result.getInt(1);
                         }
                    }
                    finally {
                         result.close();
                    }
               }
               finally {
                    statement.close();
               }
         }
         finally {
               connection.close();
         }
    }
    catch (SQLException e) {
    // Handle exception
    }
    

    您能提出一种更好(更短)的方法来执行语句,同时释放所有消耗的资源吗?

    我使用静态方法创建了一个实用程序类,我可以调用:

    package persistence;
    
    // add imports.
    
    public final class DatabaseUtils {
    
        // similar for the others Connection and Statement
        public static void close(ResultSet rs) {
            try {
                if (rs != null) {
                    rs.close();
                }
            } catch (Exception e) {
                LOGGER.error("Failed to close ResultSet", e);
            }
        }
    }
    
    所以你的代码应该是:

         Integer theOne = null;
         Connection connection = null;
         PreparedStatement statment = null;
         ResultSet result = null;
         try {
             connection = dataSource.getConnection();
             statement = connection.prepareStatement("SELECT 1 FROM myTable");
             result = statement.executeQuery();
             while (result.next()) {
                 theOne = result.getInt(1);
             }
        } catch (SQLException e) {
            // do something
        } finally {
            DatabaseUtils.close(result);
            DatabaseUtils.close(statement);
            DatabaseUtils.close(connection);
        }
        return theOne;
    
    我建议在这个方法之外实例化连接并将其传入。这样可以更好地处理事务。

    签出,尤其是签出方法。它将正确处理连接/语句/结果集关闭,包括一个或多个为null的情况


    另一种选择是,它将大量工作从您身边抽象出来,您可以以一种功能更强大的方式处理数据库查询。您只需提供一个类作为回调,以便为
    结果集的每一行调用该类。它将处理迭代、异常处理和正确关闭资源。

    如果您使用的是Java 7,该语句将大大缩短此过程,并使其更易于维护:

    try (Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement(queryString); ResultSet rs = ps.execute()) {
    
    } catch (SQLException e) {
        //Log the error somehow
    }
    

    请注意,关闭连接将关闭所有相关的
    语句
    结果集
    只需关闭
    连接
    ,即可释放所有资源*。您不需要关闭
    语句
    结果集


    *只需确保您没有任何活动事务。

    您的代码可以用这种方式缩短和编写

    Connection connection = null;
    PreparedStatement statement = null;
    ResultSet result = null;
    try {
         connection = dataSource.getConnection(); 
         statement = connection.prepareStatement("SELECT 1 FROM myTable");
         result = statement.executeQuery();
         if (result.next()) {
             Integer theOne = result.getInt(1);
         }
    }
    catch (SQLException e) { /* log error */ }
    finally {           
         if (result != null) try { result.close(); } catch (Exception e) {/*log error or ignore*/}
         if (statement != null) try { statement.close(); } catch (Exception e) {/*log error or ignore*/}
         if (connection != null) try { connection.close(); } catch (Exception e) {/*log error or ignore*/}
    }
    
    Connection connection = dataSource.getConnection();
    PreparedStatement statement = null;
    ResultSet result = null;
    try {
        statement= connection.prepareStatement("SELECT 1 FROM myTable");
        result = statement.executeQuery();
        if (result.next()) {
            Integer theOne = result.getInt(1);
        }
    } catch (SQLException e) {
        // Handle exception
    
    } finally {
        if(result != null) result.close();
        if(statement != null) statement.close();
        if(connection != null) connection.close();
    }
    

    把整件事都包起来试试看?除非您想知道它具体在哪里失败。如果您将整个块包装到try/catch中并引发异常,您将不知道哪些资源已被占用,需要关闭。@user245106我的评论有点滑稽。如果您使用的是连接池,关闭连接实际上可能不会关闭
    语句
    结果集
    。有趣的是,我不知道这一点。感谢您的提示。JdbcTemplate相当不错,+1此解决方案有一个小问题。connection.close也可能引发SQLException。评论不错。这很好地说明了一个简单的资源管理问题根本不是问题