これはWebアプリであるため、結果セットをいつ閉じる必要があるかがわかります。リクエストの最後です。結果セット/接続をリクエストスコープに登録し、リクエストの最後にそれらをすべて閉じることができます。これがColdFusion(Java上で実行)がそれを処理する方法です。
または、Mynaのように実行して、デフォルトで「マテリアライズド」コレクションを返すか、生の結果セットに対して実行されるオプションの行ハンドラーを使用することができます。2番目のケースでは、ほとんどの場合特別な処理を必要とし、コレクションに詰め込むだけでは実用的ではないBLOBなどに直接アクセスできます。また、rowHandlerがいつ実行されるかがわかっているため、結果セット/接続を閉じることができます。
アップデート:
これは、リクエスト終了時に閉じるアプローチの簡単な例です。
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オブジェクトに保持することはおそらく理にかなっていますが、それを使用するすべてのメソッドに要求を渡す必要があります。どちらの方法でも、開いている結果セットの配列を保持し、リクエストの最後にそれらを閉じる必要があります。ある種のフレームワークを使用すると、これが非常に簡単になります。