java.sql.Statement或java.sql.PreparedStatement - 带参数的可滚动结果集

时间:2016-02-23 15:21:48

标签: java sql resultset

在我的java应用程序中,它似乎在我的查询中使用参数到数据库,我需要利用PreparedStatement。 但同时,我想在前进/后退模式下使用语句的结果集(可滚动) PreparedStatement似乎没有提供设置可滚动模式 声明似乎没有提供参数。

看起来像一个基本的问题..但是没有什么东西跳出来(除了使用Statement和构造没有参数的SQL)。真的没有办法为Statement提供参数。或者有一个可滚动的预备语句吗?我错过了什么吗?

            conn = Utility.getConnection();

            tmpSQL = "SELECT * FROM " + baseTable + " WHERE " + filterCriteria
                    + " ORDER BY " + sortCriteria;

//method 1

Statement stmt = conn.createStatement(
                       ResultSet.TYPE_SCROLL_INSENSITIVE,
                       ResultSet.CONCUR_UPDATABLE);

rset = stmt.executeQuery(tmpSQL);  //not using any parameters!


//method 2

            PreparedStatement pStatement = conn.prepareStatement(tmpSQL);  //not scrollable!

            if (params != null)
                for (int i = 0; i < params.size(); i++) {

                    pStatement.setString(i + 1,
                            ((Parameter) params.get(i)).getStringValue());

                }

            rset = pStatement.executeQuery();

2 个答案:

答案 0 :(得分:6)

使用

PreparedStatement pStatement = conn.prepareStatement(tmpSQL,
                                        ResultSet.TYPE_SCROLL_INSENSITIVE,
                                        ResultSet.CONCUR_UPDATABLE);

Java Doc Info

然后要在ResultSet中获取记录数,请使用rset.last(),然后使用rset.getRow()。然后使用rset.beforeFirst()将光标放回原来的位置。

答案 1 :(得分:1)

一些初步背景评论

可滚动性主要取决于底层数据库。即使JDBC有一种向后滚动的方法,它也没有实现,例如在Oracle JDBC驱动程序中。

我建议避免滚动结果集。实际上,即使它适用于某些数据库,实现效率也很低。在GUI上使用效率也很低,因为每次滚动都会触发数据库操作,这很慢。

通常的方法是将所有行加载到容器(例如List&lt; ...&gt;)并处理该行,如果您有适度的行数(例如最多1000行)。如果你有更多的行,那么:

  • 如果你确实需要读取那么多行,请考虑一下。例如,如果这是一个GUI列表,加载100万行可能没有意义,因为人类用户不会逐行滚动所有100万行。可能更好的过滤和/或分页是有意义的。
  • 如果您确实需要所有行进行业务端处理,那么请仔细考虑一下。将所有行从数据库拉到应用程序进行处理是一种超低效的编程模式。使用存储过程或包(Oracle)来处理数据库端的数据。
  • 但如果您确实需要将1亿行拉到应用程序进行处理,请以流式方式进行处理。即而不是首先向内存中提取100万行然后处理它,获取一行,处理它,获取另一行,处理它。这也解释了为什么通常不支持反向滚动:这需要驱动程序或数据库实际在内存中保存一百万行的结果,因为可能想要向后滚动。

解决您的问题

要获取记录计数,请使用select count(*)执行单独的语句。 然后执行另一个选择以实际读取记录并获取它们(仅向前)。

比读取所有记录要快得多。