2012-04-26 8 views
0

私は非常に不十分な、大規模なwebappをクリーンアップしています。私はすぐにそれをすることはできないので、私はそれを断片的に取ります。私がしたいことの1つは、SQL文を受け取り、コレクションを返す関数を持つクラスを実装することです。私の計画は、一度それが世話をしている私は、Webアプリケーションの残りの部分を邪魔することなく、そのレイヤーを置き換えるデータベースフレームワークの周りを買い物することができます。CachedRowSet、ResultSetDynaClassまたは別のコレクション?

テンプレートスタイルのデータベースアクセス関数からResultSetを返す際の大きな問題は、ResultSetを無効にしないと接続を閉じることができないことです。

私はこの古いstackoverflow postの提案を見つけることに興奮しました。

私はCachedRowSetに掲載された記事を読んでいましたが、その記事で大量の結果を自分自身に詰め込んで多くのJVMメモリを吸い上げるのに問題が生じると書かれていました。

代替のApache ResultSetDynaClassまたは他のコレクションに同じ問題はありませんか?結果はメモリに書き込まれる必要があります。右?

ChaedRowSet、ResultSetDynaClassまたはJava Collectionを使用してResultSetデータを保存した場合、ResultSetデータを閉じるとそのデータは失われますか?

私はHashMapsを使用して、汎用データベースクエリ関数の単一レコードを格納しました。

コードを煩わせることなく複数のレコードを格納するためにJava Collectionsを使用するにはどうすればよいですか?可能であれば、他の2つのオプションよりもリソースの効率性や柔軟性が向上しますか?

事前に情報やアイデアをお寄せいただきありがとうございます。

答えて

1

これはWebアプリケーションなので、結果セットを閉じる必要があるときは、リクエストの最後にわかります。リクエストスコープで結果セット/接続を登録し、リクエストの最後にすべてを閉じることができます。 ColdFusion(Java上で実行)がこれを処理する方法です。

Mynaはデフォルトで「マテリアライズされた」コレクションを返すか、生の結果セットに対して実行されるオプションのローハンドラーを取ります。 2番目のケースでは、ほとんどの場合特別な処理が必要なBLOBのようなものに直接アクセスでき、コレクションに入れるだけでは実用的ではなく、結果セット/接続を閉じるためにrowHandlerがいつ完了するかを知ることができます。

UPDATE:ここ

がクローズ時に要求エンドアプローチの簡単な例である

public class Query { 
    static public ConcurrentHashMap  openResultSets = new java.util.concurrent.ConcurrentHashMap(); 
    public ResultSet runQuery(String sql) throws SQLException{ 
     //set up connection, run query 
     ResultSet rs = statement.executeQuery(); 
     if (Query.openResults.get(Thread.currentThread().getId()) == null){ 
      Query.openResults.put(Thread.currentThread().getId(),new Vector()) 
     } 
     Vector openRS = (Vector) Query.openResults.get(Thread.currentThread().getId()) 

     openRs.add(rs); 
     return rs; 
    } 
    public void onRequestEnd(String sql) { 
     Vector openRS = (Vector) Query.openResults.get(Thread.currentThread().getId()); 
     if (openRS != null){ 
      for (ResultSet rs : openRS.values()){ 
       try{ 
        rs.close(); 
       } catch(Exception e){} 
      } 
     } 
     //do any other request end cleanup of connections, etc 
    } 
} 

//in your servlet 
public class Query extends HttpServlet { 

    public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{ 

     ResultSet rs = Query.runQuery("select * from AWESOME"); 
     //do awesome stuff, maybe load other classes that can run runQuery 

     Query.onRequestEnd(); 
    } 
} 

これは理想的ではありませんが、私はあなたが使用しているフレームワークを知りません。おそらくsetAttribute()/ getAttribute()を介してHttpServletRequestオブジェクトにこれを保持するのが理にかなっていますが、それはそれを使用するすべてのメソッドにリクエストを渡す必要があります。どちらの方法でも、開いている結果セットの配列を保持し、要求の最後に閉じる必要があります。いくつかの種類のフレームワークを使用すると、これは簡単になります。

+0

あなたが書いたものはすべて私にとって100%新しいものなので、あなたが言った言葉は分かりません。あなたが言及した最初のアプローチが最も望ましいと思います。あなたは例と説明へのリンクを投稿できますか? – Steve

関連する問題