带资源尝试的 JDBC
Posted
技术标签:
【中文标题】带资源尝试的 JDBC【英文标题】:JDBC with try with resources 【发布时间】: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 collection
和 unhandle sql exception
statement.executeQuery(sqlQuery)
您在关闭后返回一个结果集。这行不通。
@NathanHughes 嗯,那么我怎样才能创建一个可以从 sql 查询动态返回值的 jdbc 类?例如,如果我想查询一个 clob 而不是一个字符串?我不是必须返回一个 ResultSet 吗?
可能你的JDBC
类应该返回一个对象或集合,然后是来自ResultSet 的数据并关闭然后连接。
【参考方案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 语法。你应该去阅读最新的语言手册。以上是关于带资源尝试的 JDBC的主要内容,如果未能解决你的问题,请参考以下文章