2017-01-03 11 views
-1

これは残りの部分と同様の質問です(元々、新しいものを試す前に、それはちょっとユニークでしたが、主な問題は決して解決しませんでした)が、このサイトのさまざまな投稿を既に読んでいるにもかかわらず、これを引き起こしているものを得ることができないため、助けてくれる人がいる。要するに、シーケンシャルなクエリをたくさん作成する必要がありますが、あまりにも多くの接続を作成しました。JDBCが多すぎる接続エラー

私のプログラムは、各メンバーのデータを表示し、ツリーやネットワークのようなものであることを示しています。各メンバーに必要なデータを取得するには、 (または孫のデータ)、および現在のメンバー(または孫のデータ)を指し示すメンバーを指し示すメンバーのデータなどが含まれます。したがって、なぜ私は各子供のデータを取得する必要があるため、クエリを作成し続ける必要があります。各ノードには、最低5人の子供がいると思っています.34人目のメンバーでは、「多すぎる接続」エラーが発生しました。

私は接続を開いたり閉じたりする方法を読みましたが、それでもやはり間違っていますか?私は最大接続を変更しようとしましたが、それは私にとっては長期的な解決策ではありません。ここで私はそれを行う方法は次のとおりです。

public class SQLConnect { 

private Connection con; 
private Statement st; 
private ResultSet rs; 

public SQLConnect() { 
    try { 
     Class.forName("com.mysql.jdbc.Driver"); 
     con = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbname?zeroDateTimeBehavior=convertToNull", "root", ""); 
     st = con.createStatement(); 

    } catch (ClassNotFoundException | SQLException ex) { 
     System.out.println("Error in constructor: " + ex); 
    } 
} 

//this method gets called before I make another query 
public void reconnect() { 
    try { 
     st.close(); 
     con.close(); 
     if (con.isClosed()) { 
      con = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbname", "root", ""); 
      st = con.createStatement(); 
     } 
    } catch (SQLException ex) { 
     Logger.getLogger(SQLConnect.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

//sample method on how I do queries 
public ResultSet getMemberViaMemberId(String mID) { 
    try { 
     String query = "CALL getMemberViaMemberId(" + mID + ");"; //procedure call 
     rs = st.executeQuery(query); 

    } catch (Exception ex) { 
     System.out.println("Error: " + ex); 
    } 

    return rs; 
} 

}//end of class 

私は私のJFormでそれを呼び出す方法がこの..です

SQLConnect connect; 

public Class(){ 
    connect = new SQLConnect(); 
} 

public void methodThatGetsCalledALot(String current_id){ 
    connect.reconnect(); //refer to SQLConnectClass displayed above 
    ResultSet member = connect.getMemberViaMemberId(current_id); 
    try{ 
     if (member.next()) { 
      lastName = member.getString("last_name"); 
      firstName = member.getString("first_name"); 
     } 

     //display data... 
    } catch (SQLException ex){ 
    } 
} 

コードは:

connect.reconnect(); 
ResultSet rs = connect.callSQLMethod(); 

は、最も重要なビットであると呼ばれていますすべてのクラスによって、およびデータを取得する必要があるすべてのメソッドによって異なります。私は、しばしばループ内にあり、とにかく新しいデータに置き換えられるため、ResultSetの終了を心配しないことを認めなければなりません。

私の問題は次のとおりです。あまりにも多くの接続が原因で、データをもう一度取得できなくなります。私は本当に物事を適切に閉じているのですか、何か不足していますか?どのようにこれを修正するための任意の提案?私の質問があまりにも混乱している場合は、必要に応じて詳細を追加します。ありがとうございました。誰かが私を自由に助けてくれることを熱望しているなら、私はいくつかの電子メールに行くだろう。ありがとうございました!そして、新年あけましておめでとうございます。

+0

接続が頻繁に閉鎖されています。 – e4c5

+0

これは良いデザインではありません。結果セットが大きく、別の "callSQLMethod"が必要な場合はどうなりますか? –

+0

まあ、おそらく私の理由は、接続が閉じられているので、私は結果セットに何もできないと言う例外をキャッチすることです。したがって、なぜ私はその再接続メソッドを呼び出す。 – yamahadinosaur

答えて

1

多くの接続を作成し、ResultSetを開いた状態で再帰しているようです。常に新しい接続を作成しないでください。必要なのは1つの接続だけで、いつも再接続しないでください。実際には、再接続メソッドはまったく必要ありません(接続が自動的に閉じない場合は、クエリを実行する前に閉じているかどうかを確認できます)。値の取得が完了したら、ResultSetを閉じる必要があります。

結果セットではなくデータが必要です。だから、データを取って、リソースを解放する。すなわち、ResultSet。だから、これを行う -

あなたgetMemberViaMemberIdでは、その方法自体では、ResultSetを返す結果セットを反復処理し、行のオブジェクトを作成し、コレクションにそれを格納し、ResultSetのを閉じた後、そのコレクションを返しません。そして、reconnectメソッドを呼び出さないでください。

プログラムを終了するときに持っている単一の接続を閉じます。

+0

あなたの答えは、どうやって再コーディングすべきか私の混乱を解消するので、あなたの答えはよさそうです。これを実装したら私はあなたにお返しします。しかし、あなたは正しいことを一つ得ました、接続は自動的に閉じます、そして、私は接続が閉じられた後に物事を行うことができないというエラーを受け取ります。だから私はそのエラーのために再接続を作成し、それが確実に閉じられていることを確認するために接続を再作成する前にcon.close()を追加しました。 – yamahadinosaur