ant*_*tak 5 java mysql mysql-connector
使用服务器游标获取结果和使用流获取结果在行为方面有什么区别?
前者(服务器游标)可以被激活:
通过设置useCursorFetch=true和defaultFetchSize=N连接属性中的每个语句。(其中N是大于零的数字。)
或者单独的语句通过最初的设置useCursorFetch=true或com.mysql.jdbc.Connection.setUseCursorFetch(true)在连接上,然后是java.sql.Statement.setFetchSize(N)在语句上。
后者(流)可以被激活:
通过设置java.sql.Statement.setFetchSize(Integer.MIN_VALUE)或调用语句在单个语句com.mysql.jdbc.Statement.enableStreamingResults()上。
并且可能通过defaultFetchSize=X在连接属性中设置在每个语句上,其中X是一个等于Integer.MIN_VALUE.
使用这些替代方法进行开发时需要考虑什么? 一个好的答案可能涉及性能、锁持有和资源分配(/释放)等主题。
检查Mysql的Connector/J源代码(v5.1.39):
当使用服务器游标 ( setUseCursorFetch(true)) 且结果集类型为 时TYPE_FORWARD_ONLY,“流”模式似乎只是一种特殊情况,其中获取的块仅为 1 行:
////// RowDataCursor.java /////////
private void fetchMoreRows() throws SQLException {
...
synchronized (this.owner.connection.getConnectionMutex()) {
...
int numRowsToFetch = this.owner.getFetchSize();
...
if (numRowsToFetch == Integer.MIN_VALUE) {
// Handle the case where the user used 'old' streaming result sets
numRowsToFetch = 1;
}
Run Code Online (Sandbox Code Playgroud)
另请参阅实例化的MysqlIO.java条件RowDataCursor:
//
// Handle cursor-based fetch first
//
if (this.connection.versionMeetsMinimum(5, 0, 2) && this.connection.getUseCursorFetch() && isBinaryEncoded && callingStatement != null
&& callingStatement.getFetchSize() != 0 && callingStatement.getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) {
ServerPreparedStatement prepStmt = (com.mysql.jdbc.ServerPreparedStatement) callingStatement;
boolean usingCursor = true;
Run Code Online (Sandbox Code Playgroud)
MySQL 5.7 文档指出,使用服务器游标会在服务器端生成一个临时表(如果大小允许的话,则为内存表),因此这可能会影响服务器性能。