Java ResultSet 与 postgresql 一起使用

Posted

技术标签:

【中文标题】Java ResultSet 与 postgresql 一起使用【英文标题】:Java ResultSet working with postgresql 【发布时间】:2011-12-12 16:56:10 【问题描述】:

我的数据库中有一个表,其中包含 2 列:uid1 - 某人的 id,uid2 - 他的朋友。

我想创建一个我某人的朋友的列表 - 直到 5 深度连接。

所以我构建了以下递归方法:

    private void recursive(int theUid,ResultSet rs,ArrayList<Integer> friends,int count,int next,PreparedStatement pstmt) throws SQLException
        if(count>=1 && next==theUid)
            return;
        
        else if(count>=DEPTH_OF_CONNECTION)
            return;
        

        else
            pstmt.setInt(1,next);
            rs=pstmt.executeQuery();
            count++;
            while(rs.next()) 
                friends.add(rs.getInt(1));
                recursive(theUid,rs,friends,count,rs.getInt(1),pstmt);
            
        
    

我收到以下错误:

线程“主”org.postgresql.util.PSQLException 中的异常:这个 结果集已关闭。在 org.postgresql.jdbc2.AbstractJdbc2ResultSet.checkClosed(AbstractJdbc2ResultSet.java:2654) 在 org.postgresql.jdbc2.AbstractJdbc2ResultSet.next(AbstractJdbc2ResultSet.java:1786)

你能帮我找出问题所在吗?

【问题讨论】:

你知道在 PostgreSQL 中只需一条语句就可以做到吗? 每一步都与服务器对话非常昂贵。带有recursive CTE 的单个查询将是可行的方法。 【参考方案1】:

Javadoc for jdbc Statement 说

默认情况下,每个Statement对象只能同时打开一个ResultSet对象。

所以我猜你正试图同时为同一个 PreparedStatement 打开太多结果集。

编辑:

Postgres jdbc driver doc 似乎证实了这一点:

您可以根据需要多次使用单个 Statement 实例。您可以在打开连接后立即创建一个,并在连接的整个生命周期内使用它。但您必须记住,在给定时间,每个 Statement 或 PreparedStatement 只能存在一个 ResultSet。

【讨论】:

只是为了完成您的 [正确] 答案。代码应该从结果集中获取所有朋友,关闭它,然后递归它得到的列表。 ...或使用common table expression :)【参考方案2】:

据我所知,您正在使用 ResultSet 对象来存储语句结果,然后将其作为参数传递给递归函数调用。所以基本上你正在覆盖变量并失去对它的引用。您应该编写 sql 语句来检索您需要的数据,或者不将相同的 ResultSet 对象传递给递归调用。

【讨论】:

以上是关于Java ResultSet 与 postgresql 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

Java简单的数据库连接

在Java中 Connection、Statement、ResultSet 、PreparedSta

JDBC ResultSet::RefreshRow 不适用于级联更新

Postgres:在结果集中查找特定行的位置?

ResultSet.next() 在使用 jdbc 与 oracle 11.2 交谈时挂起

如何将 ResultSet 与 oracle 包规范中声明的游标相关联?