Statement参数声明,fetchSize使用

12 篇文章 0 订阅
12 篇文章 0 订阅

一、Statement stmt=conn.createStatement(参数一,参数二)

第一个参数可以取值为
ResultSet.RTYPE_FORWORD_ONLY:这是缺省值,只可向前滚动;
ResultSet.TYPE_SCROLL_INSENSITIVE:双向滚动,但不及时更新,就是如果数据库里的数据修改过,并不在ResultSet中反应出来。
ResultSet.TYPE_SCROLL_SENSITIVE:双向滚动,并及时跟踪数据库的更新,以便更改ResultSet中的数据。

第二个参数可以取值为
ResultSet.CONCUR_READ_ONLY:这是缺省值,指定不可以更新 ResultSet
ResultSet.CONCUR_UPDATABLE:指定可以更新 ResultSet

TYPE_SCROLL_INSENSITIVE = 1004;
CONCUR_READ_ONLY = 1007;
TYPE_SCROLL_SENSITIVE = 1005;

举例:如何得到rs的记录数(第一个参数不能选默认值,否则,不能调用last,first等函数)

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

ResultSet rs = stmt.executeQuery(“select col from tb;”);

rs.last();

int n= rs.getRow();

rs.first();

二 、fetchSize

使用要求:

数据库必须使用V3协议,即pg7.4+
connection的autoCommit必须为false,因为开启autoCommit的话,查询完成cursor会被关闭,那么下次就不能再fetch了。另外ResultSet必须是ResultSet.TYPE_FORWARD_ONLY类型,这个是默认的。也就是说无法向后滚动。
查询语句必须是单条,不能是用分号组成的多条查询

根据JDK JDBC文档,ResultSet::setFetchSize()函数语义为 JDBC 驱动程序设置此 ResultSet 对象需要更多行时应该从数据库获取的行数。如果指定的获取大小为零,则 JDBC 驱动程序忽略该值,随意对获取大小作出它自己的最佳猜测。默认值由创建结果集的 Statement 对象设置。获取大小可以在任何时间更改。

但在实际使用Oracle JDBC驱动时,我们开发的程序发生了莫名的错误,总是会出现获取到的取值与数据库实际取值不一致的情形,经过仔细的测试与排查,我们发现是由于ResultSet::setFetchSize()函数调用导致的错误,在我们的测试环境中,Oracle JDBC缺省为ResultSet设定的大小为10,如果我们将其改编为100,那么一般会在获取第11条记录的第一个取值时发生获得取值与数据库实际取值不一致的问题,引发问题的语句如下:

ResultSet equipRs = roleStat.executeQuery();
if(equipRs.getFetchSize() < 20)
equipRs.setFetchSize(20);

但如果我们调用Statement的setFetchSize()函数预先设置FetchSize为期望的值,则不会引发问题:

roleStat.setFetchSize(20); // 调用Statement的setFetchSize()方法不会引发问题
ResultSet equipRs = roleStat.executeQuery();

用例:

  @Test
    public void testReadTimeout() throws SQLException {
        Connection connection = dataSource.getConnection();
        //https://jdbc.postgresql.org/documentation/head/query.html
        connection.setAutoCommit(false); //NOTE 为了设置fetchSize,必须设置为false

        String sql = "select * from demo_table";
        PreparedStatement pstmt;
        try {
            pstmt = (PreparedStatement)connection.prepareStatement(sql);
            pstmt.setFetchSize(50); 
            System.out.println("ps.getQueryTimeout():" + pstmt.getQueryTimeout());
            System.out.println("ps.getFetchSize():" + pstmt.getFetchSize());
            System.out.println("ps.getFetchDirection():" + pstmt.getFetchDirection());
            System.out.println("ps.getMaxFieldSize():" + pstmt.getMaxFieldSize());

            ResultSet rs = pstmt.executeQuery(); 
            //NOTE 这里返回了就代表statement执行完成,默认返回fetchSize的数据
            int col = rs.getMetaData().getColumnCount();
            System.out.println("============================");
            while (rs.next()) { 
                for (int i = 1; i <= col; i++) {
                    System.out.print(rs.getObject(i));
                }
                System.out.println("");
            }
            System.out.println("============================");
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //close resources
        }
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值