可以在多个类方法中使用相同的 BasicDataSource、Connection

下面的代码使用了 BasicDataSource、Sql Connection、Statement 和 ResultSet 的静态对象。下面的代码运行良好,但我只想知道使用这些编码实践的安全性。或者我该如何优化下面的代码,使其变得更加稳定和可靠。


public class Testing {

     static BasicDataSource bds = DBConnection.getInstance().getBds();

     static Connection con = null;

     static PreparedStatement stmt = null;

     static ResultSet rs = null;


    private void show() {

        try {

            con = bds.getConnection();

            stmt = con.prepareStatement("SELECT * FROM users");

            rs = stmt.executeQuery();

            if(rs.next()) {

                System.out.println(rs.getString("firstname") + " " + rs.getString("lastname"));

            }

        } catch (SQLException e) {

            e.printStackTrace();

        }finally {

            try {

                con.close();

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

    }

    private void display() {

        try {

            con = bds.getConnection();

            stmt = con.prepareStatement("SELECT * FROM agent_cities");

            rs = stmt.executeQuery();

            while(rs.next()) {

                System.out.println(rs.getString("city_name"));

            }

提前致谢。请分享您可以打破上述代码并质疑其安全性的案例。


更新: 更新只是为了确保没有人应该像我在上面的程序中使用的那样使用静态字段,因为上面的程序在部署到开发服务器上时包含错误。


在大型系统上使用上述代码后,我发现了这个错误。一个月前我对上面的代码没有任何问题,它工作正常,但今天我发现了这个错误。


漏洞:


在点击我的 API 6-7 次后,它在第 8 次点击时停止响应。我真的不知道为什么,也不知道程序中存在循环漏洞。但是现在我已经接受了答案,我更改了我的源代码并开始在我的代码中使用 try-with 资源并删除了静态字段。


但是我仍然很想知道我在上面的代码中发现的错误。在 7-8 API 命中后没有响应并挂起。请分享您对此的看法。我正在使用 apache tomcat 8.5.32 服务器。提前致谢。


临摹微笑
浏览 123回答 3
3回答

守着一只汪

更好地使用try-with-resources。这会自动关闭 Connection、Statement 和 ResultSet,即使在引发异常或内部返回时也是如此。    String sql = "UPDATE users SET firstname = ? WHERE id = ?";    try (Connection con = bds.getConnection();            PreparedStatement stmt = con.prepareStatement()) {        stmt.setString(1, "shsh");        stmt.setLong(2, 2);        stmt.executeUpdate();        System.out.println("updated successfully");    }    String sql = "SELECT city_name FROM agent_cities";    try (Connection con = bds.getConnection();            PreparedStatement stmt = con.prepareStatement()) {        try (ResultSet rs = stmt.executeQuery()) {            while(rs.next()) {                System.out.println(rs.getString("city_name"));            }        }    }这对于垃圾收集更好。防止不美观的 rs2、rs3。允许多用户并发,例如在服务器应用程序中。调用自己的查询。并且static更多的是全局变量的风格。

ITMISS

如果我们谈论这样一个小程序,它或多或少是可以的。但是没有必要将 con、stmt 和 rs 作为静态变量保留,它们可以在方法内部声明。此外,您需要重写 try catch finally 块并正确关闭资源:Connection con = null;PreparedStatement stmt = null;ResultSet rs = null;try {  // your code} catch (SQLException e) {  e.printStackTrace();} finally {  try { if (rs != null) rs.close(); } catch (Exception e) {e.printStackTrace();}  try { if (stmt != null) stmt.close(); } catch (Exception e) {e.printStackTrace();}  try { if (conn != null) conn.close(); } catch (Exception e) {e.printStackTrace();}}作为下一步,您可以检查try-with-resources构造以清理此代码。

慕盖茨4494581

您应该使用 try-with-resources 来避免任何类型的连接泄漏。以下示例从文件中读取第一行。它使用 BufferedReader 的实例从文件中读取数据。BufferedReader 是程序完成后必须关闭的资源:static String readFirstLineFromFile(String path) throws IOException {    try (BufferedReader br =                   new BufferedReader(new FileReader(path))) {        return br.readLine();    }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java