JDBC 错误“连接太多”

Posted

技术标签:

【中文标题】JDBC 错误“连接太多”【英文标题】:JDBC error "Too many connections" 【发布时间】:2015-05-10 06:58:55 【问题描述】:

我创建了一个 java swing 应用程序,其中基本上用户登录到主窗口并选择一个 jmenu 项,该项目将用户引导到一个新窗口,您可以在其中向数据库输入数据。

在更新数据库的第三个窗口中,我使用了一个 jcombobox,其中的项目是从数据库中加载的。

当我调试它时,它运行正常。但是当我尝试从上到下运行应用程序时,会显示更新窗口,但未加载 jcombobox 项。它给出了一个错误,说连接太多。

据我所知,我已正确关闭所有连接。

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)                                          
String un=jTextField1.getText();
String pwd=jPasswordField1.getText();
   if(un.isEmpty())
       JOptionPane.showMessageDialog(this,"User Name is empty");
   
   else  if(pwd.isEmpty())
       JOptionPane.showMessageDialog(this,"Password is empty");
   
   else
    try 
         DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
        Calendar cal = Calendar.getInstance();

        ResultSet rs=new DBconnect().getdata("SELECT * FROM user");
        rs.next();
        if ((rs.getString("Name").equals(un))&&(rs.getString("pw").equals(pwd)))
            new DBconnect().putdata("INSERT INTO login (Date,User) VALUES('"+dateFormat.format(cal.getTime())+"','"+un+"')");
          new  MainWindow().setVisible(true);

          this.dispose();
        
        else
            JOptionPane.showMessageDialog(this, "Invalid user name or password");
            jTextField1.setText("");
            jPasswordField1.setText("");
        
        rs.close();
     catch (Exception ex) 
        Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
    

   
                                        

以上是我的登录表单代码。

 public MainWindow() 
    setExtendedState(JFrame.MAXIMIZED_BOTH);
    new Thread()
        public void run()
            while(true)
       DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
       Calendar cal = Calendar.getInstance();

       DateFormat dateFormat2 = new SimpleDateFormat("yyyy/MM/dd");
       Calendar cal2 = Calendar.getInstance();

       jLabel1.setText(dateFormat.format(cal.getTime()));

                try 
                    ResultSet rs=new DBconnect().getdata("SELECT COUNT(Pno) FROM medicalhistory WHERE Date ='"+dateFormat2.format(cal2.getTime())+"'");
                    rs.next();
                    jLabel4.setText(rs.getString("COUNT(Pno)").toString());


                    ResultSet rs2=new DBconnect().getdata("SELECT SUM(Amount) FROM income WHERE Date ='"+dateFormat2.format(cal2.getTime())+"'");
                    rs2.next();
                    jLabel5.setText(rs2.getString("SUM(Amount)").toString());
                    rs2.close();
                    rs.close();

                 catch (Exception ex) 
                    Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
                
            
        
    .start();


    initComponents();

上面是我使用连接的主窗口代码。这些工作正常。

public addnewpatient() 
            setExtendedState(JFrame.MAXIMIZED_BOTH);


    initComponents();
        try 
                try (ResultSet rs3 = new DBconnect().getdata("SELECT Name FROM drugstock WHERE stockAmount >0")) 
                    Vector v= new Vector();
                    while(rs3.next())
                        String ids = rs3.getString("Name");
                        v.add(ids);
                        jComboBox1.addItem(ids);
                    
                    jComboBox1.addItem("Null");
                  rs3.close();
                

    


        catch (Exception ex) 
        Logger.getLogger(addnewpatient.class.getName()).log(Level.SEVERE, null, ex);
    

上面的代码给出了太多的连接错误。

putdata 和 getdata 是我在连接类中创建的两个方法,以方便使用。

:) 提前感谢:)

【问题讨论】:

请附上您在这篇文章中看到的例外情况。 【参考方案1】:

我可以看到您正在以下行中创建连接:

ResultSet rs3 = new DBconnect().*;

那么你只是关闭 ResultSet - rs3.close();

谁负责关闭您的数据库连接以及如何关闭?

现在如何解决:

您的代码中不需要内部 try 块 - 所以删除它。

获取连接:

DBconnect dbconnect = new DBconnect();
ResultSet rs3 = dbconnect..getdata("...");;

在退出 try 块之前 - 关闭 ResultSet、Connection。

rs3.close();
dbconnect.close();

如下替换您的 DBConnect.java:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;

public class DBconnect 
    static String url = "jdbc:mysql://localhost:3306/ppmgt";
    Connection conn;
    Statement st;

    public DBconnect() 

        try 
            Class.forName("com.mysql.jdbc.Driver");
            this.conn = DriverManager.getConnection(url, "root", "");
         catch (ClassNotFoundException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
         catch (SQLException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
    

    public void putdata(String sql) throws Exception 
        st = this.conn.createStatement();
        st.executeUpdate(sql);
    

    public ResultSet getdata(String sql) throws Exception 
        Statement st = this.conn.createStatement();
        return st.executeQuery(sql);
    

    public void close() 
        try 
            this.conn.close();
         catch (SQLException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
    

    public static long compareTo(Date date1, Date date2) 
        return date1.getTime() - date2.getTime();
    

除了关闭连接之外,使用 DBconnect 类的类不需要进行其他更改:

dbconnect.close();

【讨论】:

如果我使用 finally try rs.close();catch(Exception e); 它在主 try 块中给出了一个错误 请告诉我如何关闭连接。我无法在连接类的 putdata 和 getdata 方法中关闭连接。 更好的是:使用 try-with-resources。 更好的是:使用连接池。 @chrylis 在 Swing 应用程序中使用连接池可能是矫枉过正,只要连接没有被正确关闭,问题仍然存在,因为关闭连接是返回连接池的原因。 【参考方案2】:
public class DBconnect 
static String url = "jdbc:mysql://localhost:3306/ppmgt";



public static Connection con() throws Exception 
    Class.forName("com.mysql.jdbc.Driver");
    Connection c = DriverManager.getConnection(url, "root", "");
    return c;


public void putdata(String sql) throws Exception 
    Connection c = DBconnect.con();
    Statement st = c.createStatement();
    st.executeUpdate(sql);



public ResultSet getdata(String sql) throws Exception 
    Connection c = DBconnect.con();
    Statement st = c.createStatement();
    ResultSet r = st.executeQuery(sql);

    return r;


    public static long compareTo(Date date1,Date date2) 
    return date1.getTime() - date2.getTime();

这是我的 DBconnect 类

【讨论】:

以上是关于JDBC 错误“连接太多”的主要内容,如果未能解决你的问题,请参考以下文章

java jdbc中的连接太多

JAVA:MySql:连接太多

数据源拒绝建立连接,来自服务器的消息:“连接太多”

golang postgres连接太多错误

Django Postgresql Heroku:操作错误-'角色“用户名”的连接太多'

Play Framework:“连接太多”数据库错误