Isso acontece, pelo menos às vezes. Testei o comportamento do MySQL Connector/J versão 5.1.37 usando o Wireshark. Para a mesa...
CREATE TABLE lorem (
id INT AUTO_INCREMENT PRIMARY KEY,
tag VARCHAR(7),
text1 VARCHAR(255),
text2 VARCHAR(255)
)
... com dados de teste ...
id tag text1 text2
--- ------- --------------- ---------------
0 row_000 Lorem ipsum ... Lorem ipsum ...
1 row_001 Lorem ipsum ... Lorem ipsum ...
2 row_002 Lorem ipsum ... Lorem ipsum ...
...
999 row_999 Lorem ipsum ... Lorem ipsum ...
(where both `text1` and `text2` actually contain 255 characters in each row)
... e o código ...
try (Statement s = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY)) {
s.setFetchSize(Integer.MIN_VALUE);
String sql = "SELECT * FROM lorem ORDER BY id";
try (ResultSet rs = s.executeQuery(sql)) {
... imediatamente após o
s.executeQuery(sql)
– ou seja, antes de rs.next()
é até chamado – o MySQL Connector/J recuperou as primeiras ~140 linhas da tabela. Na verdade, ao consultar apenas a
tag
coluna String sql = "SELECT tag FROM lorem ORDER BY id";
O MySQL Connector/J recuperou imediatamente todas as 1000 linhas, conforme mostrado pela lista Wireshark de quadros de rede:
O quadro 19, que enviou a consulta ao servidor, ficou assim:
O servidor MySQL respondeu com o frame 20, que começou com ...
... e foi imediatamente seguido pelo quadro 21, que começou com ...
... e assim sucessivamente até que o servidor tenha enviado o quadro 32, que terminou com
Como a única diferença era a quantidade de informações retornadas para cada linha, podemos concluir que o MySQL Connector/J decide um tamanho de buffer apropriado com base no comprimento máximo de cada linha retornada e na quantidade de memória livre disponível.
O MySQL Connector/J inicialmente recupera o primeiro
fetchSize
grupo de linhas, então como rs.next()
se move através deles, eventualmente recuperará o próximo grupo de linhas. Isso é verdade mesmo para setFetchSize(1)
que, aliás, é o caminho para realmente obter apenas uma linha de cada vez. (Observe que
setFetchSize(n)
para n>0 requer useCursorFetch=true
na URL de conexão. Aparentemente, isso não é necessário para setFetchSize(Integer.MIN_VALUE)
.)