2012-04-16 62 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