2012-04-16 49 views
3

我正在写一个酒吧的库存补货系统作为我最后一年的项目。我可以从MYSQL数据库中检索信息,并且可以一次滚动查看一个结果。使用JDBC的Java - 连接太多?

我试图根据所选类别更改结果。我已经成功地使用组合框,以达致这可是类别之间移动时,我收到以下错误:在线程

异常“主要” com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:数据源拒绝建立连接,消息从服务器:“有太多的联系”

为两个单独的文件中的代码如下:

  • 的SQL查询中RetrieveStockQuery

    public JComboBox getComboBox() throws SQLException { 
        con = SQLConnect.getConnection(); 
        combo = new JComboBox(); 
        combo.removeAllItems(); 
        try { 
        stat = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); 
        rs = stat.executeQuery("SELECT categoryName FROM Category"); 
    
        while (rs.next()) { 
         combo.addItem(rs.getString("categoryName")); 
         categoryName = rs.getString("categoryName"); 
        } 
        } 
        catch (SQLException sqle) { 
        System.out.println(sqle); 
        stat.close(); 
        con.close(); 
        } 
        return combo; 
    } 
    
    //---------------------------------------------------------------- 
    
    public void retrieveStock() throws SQLException { 
    
        con = SQLConnect.getConnection(); 
        stockGUI = new ViewStockGUI(); // I THINK THIS IS WHAT IS CAUSING THE ERROR 
    
        String viewStock = "SELECT * FROM Stock where categoryName = '" + "'" + stockGUI.selected + "'"; 
        System.out.println(viewStock); 
    
        try { 
        stat = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); 
        rs = stat.executeQuery(viewStock); 
    
        while(rs.next()){ 
         stockID = rs.getInt("stockID"); 
         stockName = rs.getString("stockName"); 
         stockDescription = rs.getString("stockDescription"); 
         stockPrice = rs.getFloat("stockPrice"); 
         stockQuantity = rs.getInt("stockQuantity"); 
         categoryName = rs.getString("categoryName"); 
    
         ID = Integer.toString(stockID); 
         price = Float.toString(stockPrice); 
         quantity = Double.toString(stockQuantity); 
         stat.close(); 
         con.close(); 
    
         System.out.println("Stock ID: " + stockID + " Stock Name: " + stockName + " Stock Description: " + stockDescription + " Stock Price: " + stockPrice + " Stock Quantity:" + stockQuantity + " Category: " + categoryName); 
        }  
        } 
        catch (SQLException err) { 
        System.out.println(err.getMessage()); 
        } 
    } 
    
  • ViewStockGUI

    public class ViewStockGUI extends JPanel { 
    
        private static final long serialVersionUID = 1L; 
        final JFrame viewFrame; 
        ViewStockQuery stockQuery; 
        ViewStockQuery stockName; 
        JComboBox comboGUI; 
        String selected; 
        JComboBox combo; 
    
        public ViewStockGUI() throws SQLException { 
    
         final ViewStockQuery stock = new ViewStockQuery(); 
    
         comboGUI = stock.getComboBox(); 
         stock.retrieveStock(); 
         viewFrame = new JFrame("View Stock"); 
    
         JPanel p = new JPanel(); 
         p.setBorder (new TitledBorder(new LineBorder(Color.black, 1, true))); 
         p.setPreferredSize(new Dimension(500,400)); 
    
         JPanel p2 = new JPanel(); 
         p2.setBorder (new TitledBorder(new LineBorder(Color.black, 1, true))); 
         p2.setPreferredSize(new Dimension(500, 50)); 
    
         JPanel p3 = new JPanel(); 
         JPanel p4 = new JPanel(); 
         JPanel p5 = new JPanel(); 
         JPanel p6 = new JPanel(); 
    
         Box box = Box.createVerticalBox();   
         Box box2 = Box.createHorizontalBox(); 
         Box box3 = Box.createHorizontalBox(); 
         Box box4 = Box.createHorizontalBox(); 
    
         final JTextField textfieldStockName; 
         final JTextField textfieldStockID; 
         final JTextField textfieldStockDescription; 
         final JTextField textfieldStockPrice; 
         final JTextField textfieldStockQuantity; 
         final JTextField textfieldStockCategory; 
    
         final JLabel stockName = new JLabel("Name:"); 
         JLabel stockID = new JLabel("ID:"); 
         JLabel stockDescription = new JLabel("Description:"); 
         JLabel stockPrice = new JLabel("Price:"); 
         JLabel stockQuantity = new JLabel("Quantity:"); 
         JLabel categoryName = new JLabel("Category:"); 
    
         box.add(Box.createVerticalGlue()); 
         box.add(stockName); 
         box.add(textfieldStockName = new JTextField("")); 
         textfieldStockName.setText(stock.getStockName()); 
         textfieldStockName.setEditable(false); 
    
         box.add(stockID); 
         box.add(textfieldStockID = new JTextField("")); 
         textfieldStockID.setText(stock.getStockID()); 
         textfieldStockID.setEditable(false); 
    
         box.add(stockDescription); 
         box.add(textfieldStockDescription = new JTextField("")); 
         textfieldStockDescription.setText(stock.getStockDescription()); 
         textfieldStockDescription.setEditable(false); 
    
         box.add(stockPrice); 
         box.add(textfieldStockPrice = new JTextField("")); 
         textfieldStockPrice.setText(stock.getStockPrice()); 
         textfieldStockPrice.setEditable(false); 
    
         box.add(stockQuantity); 
         box.add(textfieldStockQuantity = new JTextField("")); 
         textfieldStockQuantity.setText(stock.getStockQuantity()); 
         textfieldStockQuantity.setEditable(false); 
    
         box.add(categoryName); 
         box.add(textfieldStockCategory = new JTextField("")); 
         textfieldStockCategory.setText(stock.getStockCategory()); 
         textfieldStockCategory.setEditable(false); 
         box.add(Box.createVerticalGlue()); 
    
         JButton next = new JButton("Next"); 
         next.addActionListener(new ActionListener() { 
         public void actionPerformed(ActionEvent e) { 
          stock.doNext(); 
          textfieldStockName.setText(stock.getStockName()); 
          textfieldStockID.setText(stock.getStockID()); 
          textfieldStockDescription.setText(stock.getStockDescription()); 
          textfieldStockPrice.setText(stock.getStockPrice()); 
          textfieldStockQuantity.setText(stock.getStockQuantity()); 
          textfieldStockCategory.setText(stock.getStockCategory()); 
         } 
         }); 
    
         JButton previous = new JButton("Previous"); 
         previous.addActionListener(new ActionListener() { 
         public void actionPerformed(ActionEvent e) { 
          stock.doPrevious(); 
          textfieldStockName.setText(stock.getStockName()); 
          textfieldStockID.setText(stock.getStockID()); 
          textfieldStockDescription.setText(stock.getStockDescription()); 
          textfieldStockPrice.setText(stock.getStockPrice()); 
          textfieldStockQuantity.setText(stock.getStockQuantity()); 
          textfieldStockCategory.setText(stock.getStockCategory()); 
         } 
         }); 
    
         final Counter counter = new Counter(); 
         final JLabel text = new JLabel(counter.getValue1()); 
    
         JButton plus = new JButton("+"); 
         plus.addActionListener(new ActionListener() { 
         public void actionPerformed(ActionEvent e) { 
          counter.increment(); 
          text.setText(counter.getValue1()); 
         } 
         }); 
    
        JButton minus = new JButton("-"); 
        minus.addActionListener(new ActionListener() { 
         public void actionPerformed(ActionEvent e) { 
         counter.decrease(); 
         text.setText(counter.getValue1()); 
         } 
        }); 
    
        JButton update = new JButton("Update"); 
        update.addActionListener(new ActionListener() { 
         public void actionPerformed(ActionEvent e) { 
         try { 
          stock.updateStock(counter.getValue1()); 
         } 
         catch (SQLException e1) { 
          e1.printStackTrace(); 
         } 
         finally { // doesn't update yet; will work on this later 
          textfieldStockQuantity.setText(stock.getStockQuantity()); 
         } 
         } 
        }); 
    
        comboGUI.addActionListener(new ActionListener() { 
         public void actionPerformed(ActionEvent e) { 
         try { 
          combo = (JComboBox) e.getSource(); 
          selected = (String)combo.getSelectedItem(); 
          textfieldStockName.setText(stock.getStockName()); 
          textfieldStockID.setText(stock.getStockID()); 
          textfieldStockDescription.setText(stock.getStockDescription()); 
          textfieldStockPrice.setText(stock.getStockPrice()); 
          textfieldStockQuantity.setText(stock.getStockQuantity()); 
          textfieldStockCategory.setText(stock.getStockCategory()); 
          stockQuery.con.close(); 
         } 
         catch (SQLException e1) { 
          e1.printStackTrace(); 
         } 
         } 
        }); 
    
    
        box.add(comboGUI);  
        box2.add(previous); 
        box2.add(next); 
        box3.add(minus); 
        box3.add(text); 
        box3.add(plus); 
        box4.add(update); 
    
        p.add(box2); 
        p.add(box); 
        p.add(box3); 
        p.add(box4); 
    
        this.add(p, BorderLayout.SOUTH); 
        } 
    } 
    

如果有人可以帮助我们将不胜感激。

+0

你能告诉我们'SQLConnect.getConnection();'的代码吗? – dash1e 2012-04-16 15:24:50

+0

可能的重复[数据源拒绝建立连接,来自服务器的消息:“连接太多”](http://stackoverflow.com/questions/3203673/data-source-rejected-establishment-of-connection-message-from -server-too-many) – duffymo 2012-04-16 15:25:01

+1

为什么连接在while循环内关闭?它应该在try catch的finally块中。 – 2012-04-16 15:26:51

回答

5

当你有太多打开的连接时,你会得到这个异常。
这是可配置的,但在你的情况下,问题出现在你的代码中。

您发布的代码很奇怪(至少)。
除非得到SQLException或者在处理结果集期间关闭连接,否则您不要关闭连接!

在任何情况下,您应该重构您的代码,以便在完成后立即关闭连接和结果集等。
例子:

try { 

    stat = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); 
    rs = stat.executeQuery("SELECT categoryName FROM Category"); 

    while (rs.next()) { 
     combo.addItem(rs.getString("categoryName")); 
     categoryName = rs.getString("categoryName"); 


    } 
} catch (SQLException sqle) { 
    System.out.println(sqle); 
} 
finally{ 
if(stat != null) stat.close(); 
if(con != null) con.close(); 
} 

通过投入finally收盘您确信该连接是无论是在正确的流量或异常关闭(我省略try-catch为清楚起见)。

所以用这种方法修改代码来关闭连接。

为了获得更好的性能,你应该看看连接池

0

如果你想使用JDBC(而不是JPA),那么我建议要么使用JdbcTemplate从春天或Java的自动资源管理(ARM)SE 7 (我还没有用ARM试过JDBC,但它应该可以工作。)

基本上,您需要关闭try-catch子句的finally块中的Closeables。

1

我想我在你的代码中看到了问题。你的代码非常奇怪,但这里是我认为正在发生的事情:

在你的ViewStockQuery类中,你有retrieveStock()方法。这个方法然后创建一个GUI类的实例,ViewStockGUI。除了这是不好的做法,它会导致一个问题就在这里,因为在ViewStockGUI的构造函数,你在retrieveStock()方法在这条线叫:

stockGUI = new ViewStockGUI(); 

你然后再调用retrieveStock()这一行:

final ViewStockQuery stock = new ViewStockQuery(); 

comboGUI = stock.getComboBox(); 
stock.retrieveStock(); 

这导致递归问题,因为你的ViewStockGUI()构造函数调用retrieveStock()方法,它创建一个连接并再次调用ViewStockGUI()构造函数将再次调用已不是CL的retrieveStock()方法提出连接并尝试打开不同的连接。希望你得到的照片。

解决它的一种方法是清理你的代码。不要在retrieveStock()中调用构造函数。找到一种不同的方式为您的查询传递选定的类别。

编辑:

写你ViewStockQuery像这样:

private String mSelected; 

public ViewStockQuery(String selectedCategory) { 
    mSelected = selectedCategory; 
} 

... 

public void retrieveStock() throws SQLException { 

    con = SQLConnect.getConnection(); 


    String viewStock = "SELECT * FROM Stock where categoryName = '" + "'" + mSelected + "'"; 
    System.out.println(viewStock); 


    try { 
... 

然后再编写ViewStockGUI中,当一个类已经选择这样一种方式,那就是当你创建ViewStockQuery并传入所选字符串。

编辑:

就像我之前说的,也有相当多的事情,你最终将需要在你的代码改变。但是,对于这个问题的目的,你可以做的是在你的ViewStockGUI,做到:

String selected = (String)combo.getSelectedItem(); 
final ViewStockQuery stock = new ViewStockQuery(selected); 

第一行从您的组合框中收集所选择的类别和第二行创建的ViewStockQuery一个实例,并将所选到构造函数。然后这将初始化mSelected,如您在上面为ViewStockQuery所提供的构造函数中所看到的那样。

+0

好吧,看着这个。 – 2012-04-17 12:37:30

+0

你把私人mSelected; 这是什么意思?一个字符串?有点困惑。 – 2012-04-17 14:46:06

+0

@LiamBull,哎呀。对不起,它意味着是一个字符串。纠正。 – ugo 2012-04-18 17:26:25