如何正确关闭MySql数据库连接

时间:2016-11-23 21:26:21

标签: java mysql

在我的Web应用程序中,我有单独的类DataAccess.java和DBUtils.java。

我在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;

我在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;
}

我从另一个servlet调用getAllCompanies函数。我不知道如何正确关闭数据库连接,因为它在一个类中打开并从另一个类调用。错误说,我的Web应用程序由于与数据库的打开连接太多而不断崩溃,

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:数据源拒绝建立连接,来自服务器的消息:“连接太多”

在这种情况下,有人可以告诉我如何正确关闭数据库连接。

3 个答案:

答案 0 :(得分:0)

您只是关闭结果集

但您没有关闭连接。

在最后一个块中请做

con.close()

请参阅此信息以获取更多信息:Closing Database Connections in Java

答案 1 :(得分:0)

基本上,您不会关闭正在创建连接泄漏的数据库connection对象。因此,您需要将DBUtil方法修改为getConnection(),如下所示。

始终close connection块中的资源(preparedstatementresultsetfinally个对象),如下所示否则会创建连接泄漏,很快就会耗尽连接。

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 等方法,以避免所有方法中的样板代码。

答案 2 :(得分:0)

我现在在DBUtils.java类中有以下代码我有以下方法

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类我有,

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

我还没有编译它,但我认为它应该没问题。再次感谢您的帮助。