【问题标题】:JDBC with try with resources带资源尝试的 JDBC
【发布时间】:2016-07-19 18:06:18
【问题描述】:

我正在尝试创建一个集中类来连接并返回 SQL 查询的 ResultSet,这样我就不必每次尝试获取查询时都创建新连接。

我正在使用try-with-resources,但是,每当我使用try-with-resources 时都会出现编译时错误,我不知道为什么?

public class JDBC {

    // logger declaration is omitted

    private static final String dbURL = "jdbc:oracle:";
    private static final String userName = "blah";
    private static final String password = "12345";

    public ResultSet retrieveSQLQuery(String sqlQuery) {            
        Connection conn = null;
        Statement statement = null;
        ResultSet rs = null;

        try (conn = DriverManager.getConnection(dbUrl, user, password);
             statement = conn.createStatement();
             rs = statement.executeQuery(sqlQuery)) {               

        } catch (SQLException e) {
            logger.info(e.getMessage());
        }                    
        return rs;        
    }
}

【问题讨论】:

  • 错误是什么?
  • @AlexandruMarina 我遇到了很多错误。一旦在 getConnection 上显示 unknown class collectionunhandle sql exception statement.executeQuery(sqlQuery)
  • 您在关闭后返回一个结果集。这行不通。
  • @NathanHughes 嗯,那么我怎样才能创建一个可以从 sql 查询动态返回值的 jdbc 类?例如,如果我想查询一个 clob 而不是一个字符串?我不是必须返回一个 ResultSet 吗?
  • 可能你的JDBC 类应该返回一个对象或集合,然后是来自ResultSet 的数据并关闭然后连接。

标签: java jdbc try-with-resources


【解决方案1】:

Java 7

当您使用try-with-resources 时,指向Closeable 资源的变量必须在try-with-resources 块内声明

此外,返回rs 是个坏主意,它会在方法完成后关闭。所以你可能会在你的方法之外得到一个SQLException(类似于“ResultSet is closed”)。您应该在 try-with-resources 块内解析 rs 并从您的方法返回 SQL 不可知对象:

public ResultSet retrieveSQLQuery(String sqlQuery) {            
    try (Connection conn = DriverManager.getConnection(dbUrl, user, password);
         Statement statement = conn.createStatement();
         ResultSet rs = statement.executeQuery(sqlQuery)) {
        MyResult result = ...; // parse rs here
        return myResult;               
    } catch (SQLException e) {
        logger.info(e.getMessage());
        // return something (empty MyResult or null) from here or rethrow the exception
        // I'd recommend to get rid of this catch block and declare the SQLException on method signature
    }                    
}

您在不正确的try-with-resources 语法上遇到编译时错误,就是这样。


更新

Java 9 Java 9 为try-with-resources 提供了更灵活的语法。您可以在try (...) 块之外声明Closeable 资源:

public ResultSet retrieveSQLQuery(String sqlQuery) {
    Connection conn = DriverManager.getConnection(dbUrl, user, password);
    try (conn; ResultSet rs = conn.createStatement().executeQuery(sqlQuery)) {
        MyResult result = ...; // parse rs here
        return myResult;               
    } catch (SQLException e) {
        // handle error
    }                    
}

【讨论】:

  • 我明白了。嗯,但是我不能返回 rs 因为它不在范围内。但是,我只是被告知我不应该返回结果集
  • 已编辑,您应该从try-block 返回
  • 嗯,但是当我从 try 块返回时,我仍然得到一个编译错误
  • 哦,是因为catch块,见更新。最好将你的方法声明为throws SQLException 并在外面捕获。
  • 添加了更多编辑,返回 rs 是个坏主意,请参阅更新的答案。
【解决方案2】:

你应该这样使用它:

   public ResultSet retrieveSQLQuery(String sqlQuery) {            
        Connection conn = null;
        Statement statement = null;
        ResultSet rs = null;

        try {      
            conn = DriverManager.getConnection(dbUrl, user, password);
            statement = conn.createStatement();
            rs = statement.executeQuery(sqlQuery);         
        } catch (SQLException e) {
            logger.info(e.getMessage());
        }                     
        return rs; 
    }

它不起作用,因为你把代码放在括号里。你应该把它放在这些括号里 -> {}。这也是显示错误的原因,因为没有类的方法如下:

    try(bla bla bla) {}

【讨论】:

  • OP 明确要求 try-with-resources 语法。你应该去阅读最新的语言手册。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-03
  • 2018-08-30
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多