0

我正在清理一个做得很糟糕的大型网络应用程序。我不能一次全部完成,所以我把它分成几部分。我想做的一件事是用函数实现一个类,该函数接受 SQL 语句,然后返回一个集合。我的计划是,一旦解决了问题,我就可以到处寻找一个数据库框架来替换该层,而不会干扰 web 应用程序的其余部分。

从模板样式数据库访问函数中返回 ResultSet 的一个大问题是我无法在不禁用 ResultSet 的情况下关闭连接。

我很高兴在这个旧的stackoverflow 帖子中找到建议。

我阅读了CachedRowSet上引用的文章,但我担心文章在哪里声明它的使用可能会通过将大量结果填充到自身中而产生吸收大量 JVM 内存的问题。

替代的 Apache ResultSetDynaClass或任何其他 Collection 不会有同样的问题吗?结果必须以一种或另一种方式写入内存。正确的?

如果我使用 ChaedRowSet、ResultSetDynaClass 或 Java 集合来存储 ResultSet 数据,我会在关闭 ResultSet 后丢失这些数据吗?

我使用 HashMaps 来存储来自通用数据库查询函数的单个记录。

我怎样才能使用 java Collections 来存储多个记录而不使代码变得繁琐?假设我可以,它会比其他两个选项更节省资源或更灵活吗?

提前感谢您提供任何信息或想法。

4

1 回答 1

1

因为这是一个 Web 应用程序,所以您知道何时需要关闭结果集:在请求结束时。您可以在请求范围内注册您的结果集/连接,并在请求结束时将它们全部关闭。这就是 Cold Fusion(在 Java 之上运行)处理它的方式。

或者你可以像Myna一样默认返回一个“物化”集合,或者采用一个可选的行处理程序,它将针对原始结果集执行。在第二种情况下,您可以直接访问诸如 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 对象中可能是有意义的,但这需要将请求传递给使用它的每个方法。无论哪种方式,您只需要保留一组打开的结果集并在请求结束时关闭它们。使用某种框架使这变得容易得多。

于 2012-04-26T18:20:51.487 回答