如何使用Try-with-Resources两次使用PreparedStatement?

3

在常规的Java Try-Catch块中使用PreparedStatements时,我可以随时更改PreparedStatement以运行不同的查询,如下所示:

String sqlStatement = "update someTable set someValue = true";
try{
    PreparedStatement pstmt = con.prepareStatement(sqlStatement);
    pstmt.executeUpdate();

    /* Here I change the query */
    String anotherSqlStatement = "update aDifferentTable set something = false";
    pstmt = con.prepareStatement(anotherSqlStatement);
    pstmt.executeUpdate();
}
catch(Exception ex){
    ...
}

如何使用Java的Try-with-Resources来正确完成此操作? 这是我尝试过的方式,但是"试图将try-with-resources语句中的资源pstmt分配"。

try(Connection con = DriverManager.getConnection(someConnection, user, password);
    PreparedStatement pstmt = con.prepareStatement(sqlStatement)){
    ResultSet rs = pstmt.executeQuery();
    ....

    /* Here I attempt to change the query, but it breaks */
    String anotherSqlStatement = "select something from someTable";
    pstmt = con.prepareStatement(anotherSqlStatement);
}
catch(Exception ex){
    ...
}

我不想再次声明变量,我知道这会失去Try-with-Resources的意义,我只想把它赋值给其他变量。该怎么做呢?


2
我不确定这是否是重复的问题;这个问题确实在尝试分配,他只是试图使用多个资源。 - chrylis -cautiouslyoptimistic-
更普遍地说,永远不要为了语义上的不同目的而重复使用变量。这会令人困惑,并且是引入错误的好方法。不可变性是你的朋友。 - charles-allen
1个回答

8
考虑一下,如果Java允许您这样做会发生什么。如果您重新分配pstmt的引用,则在第一个PreparedStatement执行后,pstmt将指向第二个PreparedStatement。close方法仅在块完成执行时调用pstmt所引用的内容,因此close永远不会在第一个PreparedStatement上调用。
相反,请使用嵌套的try-with-resources块:
try (Connection con = DriverManager.getConnection(someConnection, user, password)) {
    try (PreparedStatement pstmt = con.prepareStatement(sqlStatement)) {
        pstmt.executeUpdate();
    }

    try (PreparedStatement pstmt = con.prepareStatement(anotherSqlStatement)) {
        pstmt.executeUpdate();            
    }
}

这样就有两个不同作用域的pstmt本地变量。第一个PreparedStatement在第二个开始之前被关闭。


问题中的第二个示例使用了ResultSet...不要忘记在try-with-resources子句中包含它(它也是AutoCloseable)。@Nathan我不知道你是否想在你的示例中展示它? - charles-allen
优秀的回答 @Nathan - Gaurav
我在尝试将参数放入我的查询中(someValue = ?)时遇到了异常,有人遇到过同样的问题吗? - ⵔⴰⴼⵉⵇ ⴱⵓⵖⴰⵏⵉ
如果出现任何SQLException,您将如何回滚?在try-with-resources块的父级catch块中无法访问连接对象。 - saran3h
@saran3h:你可以做类似于https://dev59.com/VnA75IYBdhLWcg3wrrNS#3161654的事情。 - Nathan Hughes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接