2011-07-14 18 views
3

次のコードスニペットのベストプラクティスは何ですか、私はexecuteQueryがそれぞれの 'if'内で実行されるたびにすべてのstmtとrsを閉じる必要がありますか? runOnSqlServerの終わりにrsとstmtを閉じ、最後にrunメソッドを閉じます。任意のポインタをありがとう!JDBC接続/結果セット/ステートメントのベストプラクティス

public void runOnSqlServer(Connection con, String[] params, String db){ 
    try{ 
    Statement stmt = con.createStatement(); 
    ResultSet rs = null; 
    if(isVer){ 
     rs = stmt.executeQuery(micro_verSql); 
     commonAct(rs, getParameter("isVer"), 1); 
    } 
    if(isInfo){ 
     rs = stmt.executeQuery("SELECT DATABASEPROPERTYEX('"+db+"', 'COLLATION')"); 
     commonAct(rs, getParameter("isInfo"), 1); 
    } 
    }catch(SQLException){ 
    ..... 
    }finally{ 
    stmt.close(); 
    rs.close(); 
    } 
} 

public void run(CommandContext ctx) { 
    try{ 
     ... 
     runOnSqlServer(con, params, sqldb); 
     ... 
    }catch(Exception ex){ 
    }finally{ 
     if (con != null) con.close(); 
    } 
} 

答えて

3

IMHO、あなたがそれで終了したら、それはまた、あなたが常に接続を閉じる必要があり文を閉じる必要がありますし、この方法は、(最終的に)完了した後の結果セットがありますが、ユーザーを再ResultSet毎回を閉じます。

編集:再初期化

ResultSet set = statement.executeQuery(); 
set = statement2.executeQuery(); 

新しい結果セットにResultSetの「セット」を設定しています。元のセットは現在何も指していないが、まだ収集待ちの状態で開いている。

+0

男は私がexecuteQueryメソッドを呼び出し、結果セットをResultSet obj、つまりrsに割り当てるたびに、別の新しいクエリ実行結果によって割り当てられる前にこのrsを閉じる必要があると教えてくれました。 – Even

+0

もしあなたがそれを再初期化しているなら、GCがそれをピックアップするまで開いたままにすることができるので、閉じてください。しかし、あなたのコードで見たものから、あなたはそれをやっていないので、最後にそれを閉じるだけです。それは必要ではありませんが、残っている多くのものがある場合には問題が発生する可能性があります。 – RMT

+0

@実際には、それを少し見てから、RSの2番目のif文にヌルチェックを追加するほうが良いでしょうnullでないこと。もう一度設定する前に閉じる – RMT

2

あなたはすべてのデータベース・リソースを閉じる必要があります:

  1. それらが作成されたメソッドのスコープで。最終的には個別のtry/catchブロックで包まれ
  2. をブロックで作成
  3. の逆の順序で
+0

男は私がexecuteQueryメソッドを呼び出し、ResultSet objに結果を代入するたびにrsと言いました。別の新しいクエリ実行結果によって割り当てられる前にrsを閉じる必要があります。本当で必要なの? – Even

0

他の人が触れたように、finallyを使用してアイテムを閉じていることが非常に重要です。

また、接続を頻繁に開いたり閉じたりするコストを軽減するために接続プールを使用することを検討してください。 c3p0はそのようなパッケージの1つです。

1

のJava 7のとして、あなたは明らかにあなたのConnectionStatementResultSetの範囲をマークし、それらを自動的に閉じている、try-with-resourcesを使用することができます。サイドノートとして

public void runOnSqlServer(Connection con, String[] params, String db){ 
    try (Statement stmt = con.createStatement()) { 
     if(isVer){ 
      try (ResultSet rs = stmt.executeQuery(micro_verSql)) { 
       commonAct(rs, getParameter("isVer"), 1); 
      } // rs is closed here 
     } 
     if(isInfo){ 
      try (ResultSet rs = stmt.executeQuery("SELECT DATABASEPROPERTYEX('"+db+"', 'COLLATION')")) { 
       commonAct(rs, getParameter("isInfo"), 1); 
      } // rs is closed here 
     } 
    } // stmt is closed here 
    catch(SQLException){ 
     ..... 
    } 
    // finally not necessary, as rs and stmt are closed automatically 
} 

:あなたはdbは、ユーザ入力から導出されていないことを確認されない限り、"SELECT DATABASEPROPERTYEX('"+db+"', 'COLLATION')"のような構文を使用しないでくださいあなたの方法runOnSqlServer(…)は、次のようになります。文字列を連結してSQL文を作成すると、SQL injectionの脆弱性が生じます。代わりにPreparedStatementを使用してください。