专栏首页码匠的流水账聊聊jdbc statement的fetchSize

聊聊jdbc statement的fetchSize

本文主要研究一下jdbc statement的fetchSize

fetchSize

这里以postgres jdbc driver为例,主要是因为postgres的jdbc driver有公开源码,而且命名比较规范。之前看oracle jdbc,由于没有源码,反编译出来一大堆var1,var2等的变量命名,非常晦涩。 默认情况下pgjdbc driver会一次性拉取所有结果集,也就是在executeQuery的时候。对于大数据量的查询来说,非常容易造成OOM。这种场景就需要设置fetchSize,执行query的时候先返回第一批数据,之后next完一批数据之后再去拉取下一批。

但是这个有几个要求:

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

实例代码

    @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
        }
    }

小结

对于查询数据量大的场景下,非常有必要设置fetchSize,否则全量拉取很容易OOM,但是使用fetchSize的时候,要求数据能够在遍历resultSet的时候及时处理,而不是收集完所有数据返回回去再去处理。

doc

  • pgjdbc-REL9.4.1212
  • jdbc-postgresql-query
  • 正确使用MySQL JDBC setFetchSize()方法解决JDBC处理大结果集 java.lang.OutOfMemoryError: Java heap space

本文分享自微信公众号 - 码匠的流水账(geek_luandun),作者:go4it

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-01-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • spring event发布及监听实例

    spring-context-4.3.11.RELEASE-sources.jar!/org/springframework/context/event/Sim...

    codecraft
  • threeten-extra使用实例

    threeten-extra是一个基于java8的java.time的扩展包,本文简单介绍一下threeten-extra的使用实例。

    codecraft
  • 聊聊hystrix的fallback

    hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/AbstractCommand.java

    codecraft
  • 【Java小工匠聊高并发】--CountDownLatch

      在讲CountDownLatch的应用场景之前,我们先在现实生活中,找到一个对应的场景。例如班主任带一帮孩子去春游,春游回家前,班主任需要清点人数,确保每个...

    Java小工匠
  • 使用Python创建自己的Instagram滤镜|视觉实战

    不知道你有没有使用过Instagram滤镜,它们非常方便,只需单击几个按钮,就可以变换我要发布的照片。

    磐创AI
  • 使用Python创建自己的Instagram滤镜|视觉实战

    不知道你有没有使用过Instagram滤镜,它们非常方便,只需单击几个按钮,就可以变换我要发布的照片。

    OpenCV学堂
  • Java 异常处理

    异常是导致程序中断执行的一种指令流,异常一旦出现并且没有进行合理处理的化,那么程序将会中断执行。

    Mirror王宇阳
  • 一条SQL引发的“血案”:与SQL优化相关的4个案例

    导读:笔者早年间从事了多年开发工作,后因个人兴趣转做数据库。在长期的工作实践中,看到了数据库工作(特别是SQL优化)面临的种种问题。本文通过几个案例探讨一下SQ...

    用户5548425
  • Hash一致性闭环算法 - ( 适用于Redis扩容、Nginx多级缓存 等等 )

    Redis扩容采用Hash闭环、Nginx多级缓存采用Hash闭环+Lua手动负载器 等等其他需要做扩容的方案

    Parker
  • 【小家java】final修饰的变量真的不可变吗?

    这可能是大家的一个共识:如果我们希望这个变量不可变,我们可以用final进行修饰。但本篇将带你深入了解不变的含义,我相信可以让你更深的了解final的原理,也能...

    YourBatman

扫码关注云+社区

领取腾讯云代金券