【问题标题】:Static Connection method in JavaJava中的静态连接方法
【发布时间】:2021-09-28 23:44:24
【问题描述】:

我对使用静态 Connection 连接数据库感到困惑。根据我的阅读,不应使用静态连接。这是我的方法:

private static Connection conn()
    {
        
        Connection connection = null;
            
        try {
            
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            connection = (Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
            

        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | SQLException ex) {
            Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        
        return connection;
        
    }

然后用一个新的方法来得到结果:

public void getResult(ArrayList test)
    {
        
        try
        {
            
            Connection conn = conn();
            
            String sql = "select id from test";
            
            PreparedStatement ps = conn.prepareStatement(sql);
            ResultSet rs = ps.executeQuery();
            
            while(rs.next())
            {
                
               test.add(rs.getInt("id"));
                
            }
            
            conn.close();
            
        } catch (SQLException ex) {
            Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }

现在,我不知道这是否安全。每次调用方法时都会重新启动连接(?),我正在关闭它。当然,连接池对性能有好处,但是这个线程安全吗?

【问题讨论】:

  • 从技术上讲,它是线程安全的,但如果抛出异常,则容易发生连接泄漏。在这种情况下不会调用conn.close()conn.close() 应该在 finally 块中,或者修改为使用 try-with-resources 的代码,这将隐式调用它。
  • 这是否意味着我可以在带有 finally 块的网络应用程序中使用它并且它仍然是线程安全的?
  • 对不起,现在我看到你已经回答了这个问题。我想将您的评论标记为答案。
  • 我将信息复制到了答案中,并添加了更多细节以使其值得成为答案。 :)

标签: java sql static connection


【解决方案1】:

从技术上讲,它是线程安全的,但如果抛出异常,则容易发生连接泄漏。在这种情况下不会调用conn.close()conn.close() 应该在 finally 块中,或者修改为使用 try-with-resources 的代码,这将隐式调用它。

try-with-resources (Java 7+) 允许在 try 语句中声明实现 Autocloseable 接口的变量。然后在try 块的末尾优雅地关闭这些变量。

try( Connection conn = conn(); ) 
{
  //.... other statements
} catch(SQLException e) {
  //.... exception code
}

【讨论】:

    【解决方案2】:

    如果您想使用单个连接,您可以在创建新连接之前声明Connection object as private instance object 并始终声明check if it is null

    private Connection connection = null;
    private static Connection conn()
    {
        
        if ( connection == null) {
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            connection = (Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
    
          } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | SQLException ex) {
            Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
          }
    
        }
        
        return connection;
    }
    

    public void getResult(ArrayList test)
    {
        
        try
        {
            Connection conn = conn();
            
            String sql = "select id from test";
            
            PreparedStatement ps = conn.prepareStatement(sql);
            ResultSet rs = ps.executeQuery();
            
            while(rs.next())
            {
                
               test.add(rs.getInt("id"));
                
            }
            
        } catch (SQLException ex) {
            Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
        }
         finally{
           try {
             conn.close();
             conn = null;
           }
           catch(Exception e)
           {
             //Unable to close connection
           }
         }
        
    }
    

    【讨论】:

      猜你喜欢
      • 2014-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      • 2012-07-13
      • 2022-12-12
      • 2018-10-04
      相关资源
      最近更新 更多