Comme Mark Rotteveel le mentionne dans un commentaire à la question, MySQL met en cache les données ResultSet par défaut (également abordé dans un article de blog de Ben J. Christensen ici ). Un effet secondaire apparent de cette mise en cache est que MySQL Connector/J « mettra à jour » un ResultSet TYPE_FORWARD_ONLY pour qu'il soit réellement défilable :
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()));
affiche
Current row number: 3
Current row number: 2
Selon l'article de blog cité ci-dessus, le moyen d'empêcher la mise en cache et de "diffuser" les données ResultSet consiste à utiliser 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());
}
entraînant
Data from first row: Gord
now let's try rs.last() ...
... Exception: Operation not supported for streaming result sets