使用一个连接样式选择执行两个Java PreparedStatements

好吧,我已经意识到我真的已经问过太多问题而没有回馈社区,但我希望你对此有所了解。 如果我有话

private void closeAll(ResultSet rs, PreparedStatement ps, Connection con) { if (rs != null) try { rs.close(); } catch (SQLException e) { } if (ps != null) try { ps.close(); } catch (SQLException e) { } if (con != null) try { con.close(); } catch (SQLException e) { } } 

我想用一个连接在MySQL数据库上做几个操作。 写作更好吗?

 Connection con = ...; PreparedStatement ps = null; ResultSet rs = null; try { ps = con.prepareStatement(...); rs = ps.executeQuery(); if (rs.next()) ...; } catch (SQLException e) { System.err.println("Error: " + e); } finally { closeAll(rs, ps, null); } try { ps = con.prepareStatement(...); rs = ps.executeQuery(); if (rs.next()) ...; } catch (SQLException e) { System.err.println("Error: " + e); } finally { closeAll(rs, ps, con); } 

要么

 Connection con = ...; PreparedStatement ps = null; ResultSet rs = null; try { ps = con.prepareStatement(...); rs = ps.executeQuery(); if (rs.next()) ...; rs.close(); ps.close(); ps = con.prepareStatement(...); rs = ps.executeQuery(); if (rs.next()) ...; } catch (SQLException e) { System.err.println("Error: " + e); } finally { closeAll(rs, ps, con); } 

我认为更好的意思是更安全,更清晰,更简洁或更强大。 我不确定后者是否会一直关闭任何准备好的语句和结果集在遇到exception时都是打开的,而我相信它确实看起来更简洁。 但前者看起来更好,因为它更加一致,但由于它使用了更多的try finally块,因此它会增加开销。

我意识到Java 7的Project Coin自动资源管理部分将迫使我倾向于前者,因为标题中使用的资源是隐含的最终版本。 但是,在我不得不担心修改我的代码以使其适应ARM并且能够删除样板代码之前我还有一段时间,所以问题仍然存在:在上述两种样式中,哪种更好的做法? 如果他们都做了预期的行为,后者会给我一个明显的性能提升,可以原谅“丑陋”的风格吗?

在我看来,这是个人偏好的情况。 在我的时代,我编写了类似于两个块的代码。 至于性能,我认为不会有特别显着的差异,只有性能测试才能说明。

可能的情况是,一个版本提供的毫秒左右的差异并不是十分钟左右的重要一半,以至于另一个人在您编写代码六个月后阅读代码时会花费时间来询问原因。

我个人的偏好是第二个。 你说你持有一个对数据库开放的连接。 使用第一个代码块,如果你得到一个exception抛出,那将被处理但是你会下降到第二个try / catch并再试一次。 如果第一个失败,您可能不希望这样。 对于第二个,例外情况会导致您退出代码然后关闭连接。

我主要用C#编程。 大约八年前,我上次做任何Java。 但我认为有很多C#程序员都在考虑这个问题。 无论如何我都有。

如果你看一下,你会发现逻辑有些不同 – 即使第一个查询处理失败,第一个版本也会执行第二个查询。 如果处理第一个查询+结果将成功,则第二个版本将继续执行第二个查询。

第二个是要走的路。 当第一个try-block中发生exception时,第一个可能无法关闭连接。 当你只是在catch-block中打印到stderr然后没有,但你不会这样做。 或者第二个陈述是否应该在不考虑第一个陈述的成功/失败的情况下执行?

我意识到这篇文章很老,但如果你有幸在Java7环境中运行 – 我会建议使用try-with-resource 。

它将为您处理连接关闭 – 因为该类的新版本实现了Closable接口。

 public static void viewTable(Connection con) throws SQLException { String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES"; try (Statement stmt = con.createStatement()) { ResultSet rs = stmt.executeQuery(query); while (rs.next()) { String coffeeName = rs.getString("COF_NAME"); int supplierID = rs.getInt("SUP_ID"); float price = rs.getFloat("PRICE"); int sales = rs.getInt("SALES"); int total = rs.getInt("TOTAL"); System.out.println(coffeeName + ", " + supplierID + ", " + price + ", " + sales + ", " + total); } } catch (SQLException e) { JDBCTutorialUtilities.printSQLException(e); } }