2016-11-23 3 views
0

私のWebアプリケーションでは、DataAccess.javaとDBUtils.javaというクラスが別々に用意されています。MySqlデータベース接続を正しく閉じるには

私はDataAccess.javaクラス

public static List<Company> getAllCompanies(){ 
    List<Company> ls = new LinkedList<>(); 

    try { 
     String sql = "select * from company"; 
     ResultSet rs = DBUtils.getPreparedStatement(sql).executeQuery();    
     while (rs.next()){ 
      Company cp = new Company (rs.getInt(1), rs.getString(2), rs.getInt(3),rs.getTimestamp(9)); 
      ls.add(cp); 
     } 
     rs.close();    
    } catch (ClassNotFoundException | SQLException ex) { 
     Logger.getLogger(DataAccess.class.getName()).log(Level.SEVERE, null, ex); 
    } 

    return ls; 
} 

内のコードを以下の持っていると私は別のサーブレットからgetAllCompanies関数を呼び出していますDBUtils.jva

public static PreparedStatement getPreparedStatement(String sql) throws ClassNotFoundException, SQLException{ 
    PreparedStatement ps = null; 
    Class.forName("com.mysql.jdbc.Driver"); 
    String url = "jdbc:mysql://localhost:3306/company"; 
    String user = "root"; 
    String pass = "root"; 

    Connection con = DriverManager.getConnection(url, user, pass); 
    ps = con.prepareStatement(sql);  

    return ps; 

のコードを次のようしています。あるクラスで開かれ、別のクラスから呼び出されるため、データベース接続を適切に閉じる方法がわかりません。私のWebアプリケーションは、データベースへの接続が多すぎるためクラッシュし続けます。エラーは次のように表示されます。

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:データソースがサーバーからの接続の確立を拒否しました:

このケースでは、データベース接続を正しく閉じる方法を教えてください。

答えて

0

は基本的には、接続リークを作成しているデータベースconnectionオブジェクトをクローズされません。したがって、DBUtilメソッドをgetConnection()に変更する必要があります。 finallyブロックで

必ずcloseリソース(connectionpreparedstatementresultsetオブジェクト)は、以下に示すように、それ以外の場合は、接続リークを作成し、非常にすぐに接続の外に実行されます。

DBUTILのgetConnection():

public static Connection getConnection() throws ClassNotFoundException, SQLException{ 
    PreparedStatement ps = null; 
    Class.forName("com.mysql.jdbc.Driver"); 
    String url = "jdbc:mysql://localhost:3306/company"; 
    String user = "root"; 
    String pass = "root"; 

    Connection con = DriverManager.getConnection(url, user, pass); 
    return con; 
} 

getAllCompanies()コード:

public static List<Company> getAllCompanies(){ 
    List<Company> ls = new LinkedList<>(); 
    PreparedStatement pstmt = null; 
    ResultSet rs = null; 
    Connection conn = null; 
    try { 
     String sql = "select * from company"; 
     conn = DBUtils.getConnection(); 
     pstmt = conn.prepareStatement(sql);  
     rs = pstmt.executeQuery();    
     while (rs.next()){ 
      Company cp = new Company (rs.getInt(1), rs.getString(2), rs.getInt(3),rs.getTimestamp(9)); 
      ls.add(cp); 
     } 

    } catch (ClassNotFoundException | SQLException ex) { 
     Logger.getLogger(DataAccess.class.getName()).log(Level.SEVERE, null, ex); 
    } finally { 
     if(rs != null) { 
      rs.close(); 
     } 
     if(pstmt !=null) { 
      pstmt.close(); 
     } 
     if(conn != null) { 
      conn.close(); 
     } 
    } 
    return ls; 
} 

また、私は強くcloseConnection()closeResultSet()closePreparedStatement()のようなメソッドを作成にあなたを示唆あなたのDBUtilクラスで順番にすべての方法で定型句コードを避けることができます。

+0

ありがとうございました。それは完璧な意味合いがあります。 closeConnection()、closeResultSet()、closePreparedStatement()などのメソッドで何を記述しますか。それらを閉じるには1行しかかからず、これらのメソッドとDBUtilsを作成すると、とにかく1行で呼び出すことになります。何がお勧めですか。 – Monauwar

0

私は、私はまだそれをコンパイルしていないが、私は思う

public static List<Company> getAllCompanies(){ 
    List<Company> ls = new LinkedList<>(); 
    ResultSet rs = null; 
    PreparedStatement ps = null;   
    Connection conn = null; 
    try { 
     String sql = "select * from company"; 
     conn = DBUtils.getConnection(); 
     ps = conn.prepareStatement(sql); 
     rs = ps.executeQuery(); 
     while (rs.next()){ 
      Company cp = new Company (rs.getInt(1), rs.getString(2), rs.getInt(3), rs.getTimestamp(9)); 
      ls.add(cp); 
     } 
    } catch (ClassNotFoundException | SQLException ex) { 
     Logger.getLogger(DataAccess.class.getName()).log(Level.SEVERE, null, ex); 
    }finally { 
     DBUtils.closeResultSet(rs); 
     DBUtils.closePreparedStatement(ps); 
     DBUtils.closeConnection(conn); 
    } 

、私は方法

public static void closeResultSet(ResultSet rs) throws ClassNotFoundException, SQLException { 
    if(rs != null) { 
     try { 
      rs.close(); 
     } catch (SQLException ex) { 
      Logger.getLogger(DataAccess.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

public static void closePreparedStatement(PreparedStatement ps) throws ClassNotFoundException, SQLException { 
    if(ps != null) { 
     try { 
      ps.close(); 
     } catch (SQLException ex) { 
      Logger.getLogger(DataAccess.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

public static void closeConnection(Connection conn) throws ClassNotFoundException, SQLException { 
    if(conn != null) { 
     try { 
      conn.close(); 
     } catch (SQLException ex) { 
      Logger.getLogger(DataAccess.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

そして、私が持っているDataAccess.javaクラスで

を次しているDBUtils.javaクラスで、今のコードを次していますそれはうまくいくはずです。助けてくれてありがとう。

関連する問題