jdbc的setFetchSize

768 阅读1分钟

默认情况下executeQuery会一次性拉取所有的查询数据,但是当遇到大数据量时,非常容易造成OOM。这种场景需要设置fetchSize,执行的时候会先拉取第一批数据,之后next结束一批数据后再重新拉取下一批数据。

实例代码

try {
    if (null == conn) {
        conn = jdbcUtil.getConnection();
    }
    java.sql.Date startTime = CommonUtils.isNotNull(dataAnalysisReport.getRecordTimeStart()) ? new java.sql.Date(dataAnalysisReport.getRecordTimeStart().getTime()) : null;
    java.sql.Date endTime = CommonUtils.isNotNull(dataAnalysisReport.getRecordTimeEnd()) ? new java.sql.Date(dataAnalysisReport.getRecordTimeEnd().getTime()) : null;
    stmt  = conn.prepareStatement(sql1.toString());
    stmt.setDate(1, startTime);
    stmt.setDate(2, endTime);
    if (isNewYear) {
        stmt.setDate(3, startTime);
        stmt.setDate(4, endTime);
    }
    // 设置每次取的数据
    stmt.setFetchSize(1000);
    ResultSet rs = stmt.executeQuery();
    while(rs.next()){
        Map<String, Object> item = new HashMap<String, Object>();
        item.put("checkinId", rs.getString(1));
        item.put("targetId", rs.getString(2));
        item.put("name", rs.getString(3));
        item.put("unit", rs.getString(4));
        item.put("results", rs.getString(5));
        item.put("targetPro",rs.getString(6));
        item.put("spTargetContrast",rs.getString(7));
        mapList.add(item);
    }
    jdbcUtil.free(rs, stmt, conn);
} catch (SQLException e) {
    logger.error(String.format("执行sql查询异常:%s", e.getMessage()));
    // 抛出异常 ,让上级事务回滚
    throw new RuntimeException(e);
}

这里设置了fetchSize后执行速度明显快了很多,具体设置多大得看实际上服务器的配置了。

如果是使用的mybatis,设置fetchSize更方便,如下:

实例代码

<select id="getLyRegisterList" fetchSize="1000" resultType="DynaBean">

数据库都是使用的Oracle