Como menciona Mark Rotteveel en un comentario a la pregunta, MySQL almacena en caché los datos de ResultSet de forma predeterminada (también discutido en un artículo de blog de Ben J. Christensen aquí ). Un efecto secundario aparente de este almacenamiento en caché es que MySQL Connector/J "actualizará" un conjunto de resultados TYPE_FORWARD_ONLY para que sea realmente desplazable:
Statement s = dbConnection.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs = s.executeQuery("SELECT * FROM testdata");
rs.last();
System.out.println(String.format("Current row number: %d", rs.getRow()));
rs.previous();
System.out.println(String.format("Current row number: %d", rs.getRow()));
muestra
Current row number: 3
Current row number: 2
De acuerdo con el artículo del blog citado anteriormente, la forma de evitar el almacenamiento en caché y "transmitir" los datos de ResultSet es usar Statement.setFetchSize
:
Statement s = dbConnection.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
s.setFetchSize(Integer.MIN_VALUE);
ResultSet rs = s.executeQuery("SELECT * FROM testdata");
rs.next();
System.out.println("Data from first row: " + rs.getString(2));
System.out.println("now let's try rs.last() ...");
try {
rs.last();
System.out.println("... Okay, done.");
} catch (Exception e) {
System.out.println("... Exception: " + e.getMessage());
}
resultando en
Data from first row: Gord
now let's try rs.last() ...
... Exception: Operation not supported for streaming result sets