JDBCmysql⼤数据量流式读取
梯形怎么画
总结下这周帮助客户解决报表⽣成操作的mysql 驱动的使⽤上的⼀些问题,与解决⽅案。由于⽣成报表逻辑要从数据库读取⼤量数据并在内存中加⼯处理后再⽣成⼤量的汇总数据然后写⼊到数据库。基本流程是 读取->处理->写⼊。
读取操作开始遇到的问题是当sql查询数据量⽐较⼤时候基本读不出来。开始以为是rver端处理太慢。但是在控制台是可以⽴即返回数据的。于是在应⽤这边抓包,发现也是发送sql后⽴即有数据返回。但是执⾏ResultSet的next⽅法确实阻塞的。查⽂档翻代码原来mysql驱动默认的⾏为是需要把整个结果全部读取到内存中才开始允许应⽤读取结果。显然与期望的⾏为不⼀致,期望的⾏为是流的⽅式读取,当结果从myql服务端返回后⽴即还是读取处理。这样应⽤就不需要⼤量内存来存储这个结果集。正确的流式读取⽅式代码⽰例:
PreparedStatement ps = connection.prepareStatement("lect .. from ..",冰箱排名前十的品牌
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
//forward only read only也是mysql 驱动的默认值,所以不指定也是可以的⽐如: PreparedStatement ps = connection.prepareStatement("lect .. from ..");
ps.tFetchSize(Integer.MIN_VALUE); //也可以修改jdbc url通过defaultFetchSize参数来设置,这样默认所以的返回结果都是通过流⽅式读取.
ResultSet rs = ps.executeQuery();
while (rs.next()) {
System.out.String("fieldName"));
}
代码分析:下⾯是mysql判断是否开启流式读取结果的⽅法,有三个条件forward-only,read-only,fatch size是Integer.MIN_VALUE
/**
栗蘑* We only stream result ts when they are forward-only, read-only, and the
* fetch size has been t to Integer.MIN_VALUE
散打教学与训练*
* @return true if this result t should be streamed row at-a-time, rather
* than read all at once.
*/船用发动机
protected boolean createStreamingResultSet() {
try {
干巴爹什么意思
三国演义人物介绍synchronized(checkClod().getConnectionMutex()) {
return ((sultSetType == java.sql.ResultSet.TYPE_FORWARD_ONLY)
&& (sultSetConcurrency == java.sql.ResultSet.CONCUR_READ_ONLY) && (this.fetchSize == Integer.MIN_VALUE));
}
奶油小方} catch (SQLException e) {
// we can't break the interface, having this be no-op in ca of error is ok
return fal;
}
}