解析JDBC使用查询MySQL【非流式、流式、游标】
解析JDBC使用游标查询MySQL
使用jdbc查询MySQL数据库,如果使用游标或者流式查询的话,则可以有效解决OOM的问题,否则MySQL驱动就会把数据集全部查询出来加载到内存里面,这样在大数据的情况下会OOM的
不同的查询方式 ResultsetRows 的实现是不一样的!!!
流式查询【每次只取一条】
流式查询的条件是
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * from dwd_data_gen", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
// 每批拉取的数据量
preparedStatement.setFetchSize(Integer.MIN_VALUE);
代码
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * from dwd_data_gen", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
// 每批拉取的数据量
preparedStatement.setFetchSize(Integer.MIN_VALUE);
# 流式查询的时候,preparedStatement.executeQuery()并不会把数据取过来,而是调用resultSet.next()的时候 从服务端取一条数据过来。该方式不会出现OOM,因为每次都是只取一条数据
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
i++;
}
非流式查询【一次性全部查出来】
流式查询的条件不满足的时候就会在preparedStatement.executeQuery()的时候 把所有数据查出来
resultSet.next()只是从上面查出来的结果里面做判断而已,不会再从数据库取数据了
游标查询【每次取fetchSize条】
游标查询的条件是
jdbc的url里面加上useCursorFetch=true的参数
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * from dwd_data_gen", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
// 每批拉取的数据量
preparedStatement.setFetchSize(1024);