【问题标题】:CachedRowSet, ResultSetDynaClass or Another Collection?CachedRowSet、ResultSetDynaClass 还是其他集合?
【发布时间】:2012-04-26 18:09:24
【问题描述】:

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

从模板样式数据库访问函数中返回 ResultSet 的最大问题是,如果不禁用 ResultSet,我无法关闭连接。

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

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

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

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

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

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

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

【问题讨论】:

    标签: java collections jdbc resultset cachedrowset


    【解决方案1】:

    因为这是一个网络应用程序,所以您知道何时需要关闭结果集:在请求结束时。您可以在请求范围内注册您的结果集/连接,并在请求结束时将它们全部关闭。这就是 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 对象中可能是有意义的,但这需要将请求传递给使用它的每个方法。无论哪种方式,您只需要保留一组打开的结果集并在请求结束时关闭它们。使用某种框架使这变得容易得多。

    【讨论】:

    • 你写的一切对我来说都是 100% 新的,所以我一个字都听不懂。您提到的第一种方法听起来是最可取的。您可以发布示例和说明的链接吗?
    猜你喜欢
    • 2013-08-07
    • 2018-12-20
    • 2019-09-02
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    • 2015-04-06
    • 2010-09-11
    相关资源
    最近更新 更多