Java 中的静态连接方法

Static Connection method in Java

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

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);
        }
        
    }

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

如果您想使用单个连接,您可以在创建新连接之前声明 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
       }
     }
    
}

从技术上讲它是线程安全的,但如果抛出异常则容易发生连接泄漏。 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
}