当前位置:网站首页>Jdbc流式查询与游标查询
Jdbc流式查询与游标查询
2022-07-26 05:41:00 【CaptHua】
源码基于mysql-connector-5.1
1.获取statement
PreparedStatement statement = conn.prepareStatement(sql,ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);
ResultSet resultSet = statement.executeQuery();
prepareStatement()方法中resultSetType的默认值为ResultSet.TYPE_FORWARD_ONLY,resultSetConcurrency的默认值为ResultSet.CONCUR_READ_ONLY

2.获取结果集
com.mysql.jdbc.MysqlIO
protected ResultSetImpl getResultSet(StatementImpl callingStatement, long columnCount, int maxRows, int resultSetType, int resultSetConcurrency,
boolean streamResults, String catalog, boolean isBinaryEncoded, Field[] metadataFromCache) throws SQLException {
if (this.connection.versionMeetsMinimum(5, 0, 2) && this.connection.getUseCursorFetch() && isBinaryEncoded && callingStatement != null
&& callingStatement.getFetchSize() != 0 && callingStatement.getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) {
if (usingCursor) {
RowData rows = new RowDataCursor(this, prepStmt, fields);
ResultSetImpl rs = buildResultSetWithRows(callingStatement, catalog, fields, rows, resultSetType, resultSetConcurrency, isBinaryEncoded);
if (usingCursor) {
rs.setFetchSize(callingStatement.getFetchSize());
}
return rs;
}
}
if (!streamResults) {
rowData = readSingleRowSet(columnCount, maxRows, resultSetConcurrency, isBinaryEncoded, (metadataFromCache == null) ? fields : metadataFromCache);
} else {
rowData = new RowDataDynamic(this, (int) columnCount, (metadataFromCache == null) ? fields : metadataFromCache, isBinaryEncoded);
this.streamingData = rowData;
}
ResultSetImpl rs = buildResultSetWithRows(callingStatement, catalog, (metadataFromCache == null) ? fields : metadataFromCache, rowData, resultSetType,
resultSetConcurrency, isBinaryEncoded);
return rs;
}
由以上代码得知,普通查询,流失查询与游标查询返回的结果集是不同的。
3.普通查询
默认是普通查询
在readSingleRowSet()方法中,将所有数据加到rows(ArrayList)中,返回静态行数据(RowDataStatic)
4.流式查询
不一次性将所有数据加载到内存,在调用next()方法时,MySQL驱动只从网络数据流获取到1条数据,然后返回应用
开启方式
- 设置statement.setFetchSize(Integer.MIN_VALUE);
- 调用createStreamingResultSet()
void enableStreamingResults() throws SQLException;
mysql-connector-8
((com.mysql.cj.jdbc.JdbcStatement)statement).enableStreamingResults()
mysql-connector-5.1
((com.mysql.jdbc.Statement)statement).enableStreamingResults()
StatementImpl.java
/** * We only stream result sets when they are forward-only, read-only, and the * fetch size has been set to Integer.MIN_VALUE * * @return true if this result set should be streamed row at-a-time, rather * than read all at once. */
protected boolean createStreamingResultSet() {
return ((this.query.getResultType() == Type.FORWARD_ONLY) && (this.resultSetConcurrency == java.sql.ResultSet.CONCUR_READ_ONLY)
&& (this.query.getResultFetchSize() == Integer.MIN_VALUE));
}
前面两个参数是默认值,所以只需要设置fetchSize为Integer.MIN_VALUE即可,这个是mysql-connector中自定义的的特殊值,在JDBC接口中没有规范。
enableStreamingResults()也可以开启流式查询,但这不是jdbc接口。
获取数据过程
- 返回动态行数据

- 每次调用resultSet.next()时,才会取一条数据

5.游标查询
每次从服务器检索fetchSize行数据,调用next()遍历完后,会再次从服务器取数据。
开启方式
url=jdbc:mysql://192.168.9.19:3307/test?useCursorFetch=true
statement.setFetchSize(20);
获取数据过程
- 返回游标行数据

- 每次调用resultSet.next()时,判断当前fetch的位置,如果不小于(size-1)的话,就会再次取数据

- 在fetchMoreRows()中会给mysql发送一个带有fetchSize的fetch命令,调用nextRow取数据

6. 总结
- 这三种方式都会调用 MysqlIO#ResultSetRow nextRow()方法获取数据。
- 游标查询也属于流式查询的一种,只不过每次从服务器读取的数据量可以设置。
- 流式查询(包含游标)会使用阻塞的方式从mysql取数据,所以必须在结果集中读取所有行(或者关闭)后才能在该连接上发起其他查询,否则会抛出异常。
There are some caveats with this approach. You must read all of the rows in the result set (or close it) before you can issue any other queries on the connection, or an exception will be thrown.
边栏推荐
- Yuancosmos provides a digital social platform for fashion design display
- 电机控制专栏文章汇总
- Development to testing: a six-year road to automation from scratch
- 520送什么?DIY一个高颜值RGB时钟,女生看了都想要
- Mongondb API usage
- Redis transaction
- 项目版本号怎么命名?看起来牛B
- Basic methods of realizing licensing function in C language
- 秋招-准备计划
- Redis official visualization tool, with high appearance value and powerful functions!
猜你喜欢
随机推荐
Polymer physics test question bank
Day011 one dimensional array
Use latex to typeset multiple-choice test paper
数仓搭建-DIM层
Embedded development notes, practical knowledge sharing
OD-Paper【2】:Fast R-CNN
嵌入式通用学习路线整理
[MySQL must know and know] time function number function string function condition judgment
SSTI payload and various bypass methods
Nn.moudle module - details of creating neural network structure
Circular structure practice
Is it really hopeless to choose electronic engineering and be discouraged?
又一开源神器,值得收藏学习!
中文文本纠错任务简介
High frequency electronic circuit review examination questions and answers
jupyter notebook快捷键
NFT in the eyes of blackash: the platform is crying for slaughter, and users send money to the door
[STM32 series summary] blogger's way to quickly advance STM32 in actual combat (continuous update)
It's enough for newcomers to learn how to do functional tests
Attack and defense world -- easy_ web









