2009-05-13 4 views
27

J'ai une page .jsp où j'ai une table d'interface graphique qui affiche les enregistrements d'une base de données Oracle. Cette table permet un comportement de pagination typique, tel que "PREMIER", "SUIVANT", "PRECEDENT" et "DERNIER". Les enregistrements sont obtenus à partir d'un objet Java ResultSet renvoyé par l'exécution d'une instruction SQL.Un ResultSet charge-t-il toutes les données en mémoire ou uniquement lorsqu'elles sont demandées?

Ce ResultSet peut être très grand, donc ma question est:

Si j'ai un ResultSet contenant un million d'enregistrements, mais ma table affiche uniquement les données des dix premiers enregistrements du ResultSet, est seulement les données extraites lorsque je commence à demander des données d'enregistrement ou toutes les données sont-elles chargées en mémoire une fois que ResultSet est renvoyé suite à l'exécution d'une instruction SQL?

Répondre

30

Java ResultSet est un pointeur (ou un curseur) vers les résultats dans la base de données. Le ResultSet charge les enregistrements dans des blocs de la base de données. Donc, pour répondre à votre question, les données ne sont récupérées que lorsque vous le demandez mais en blocs.

Si vous devez contrôler le nombre de lignes récupérées en même temps par le pilote, vous pouvez utiliser la méthode setFetchSize() sur le ResultSet. Cela vous permettra de contrôler la taille des blocs qu'il récupère à la fois.

+0

-t-pilote MySql (mysql-connector-j) soutenir un tel comportement "intelligent"? – Roman

+0

@Roman L'API JDBC n'indique pas qu'il s'agit d'une méthode facultative. Je suppose que toutes les implémentations, y compris mysql, supporteraient cela. –

+0

Si "toute la mise en œuvre prend en charge" alors comment JDBC-ODBC pont peut le faire pour MS Access? L'accès ne supporte pas les "limites" ou quelque chose de similaire, n'est-ce pas? – Roman

1

Bien que la spécification JDBC ne spécifie pas si toutes les données du jeu de résultats seront récupérées, tout pilote bien écrit ne le fera pas.

Cela dit, un jeu de résultats scrollable peut-être plus ce que vous avez à l'esprit: (lien expurgée, pointer sur une autre page spyware)

Vous pouvez également envisager un ensemble de lignes déconnectées, qui est stocké dans la session (selon l'évolutivité de votre site): http://java.sun.com/j2se/1.4.2/docs/api/javax/sql/RowSet.html

+1

FYI: Le exampledepot.com jette un message d'avertissement "harddrive doit être fragmenté". – Khanna111

9

La spécification JDBC ne spécifie pas si les données sont diffusées ou si elles sont chargées en mémoire. Oracle flux par défaut. MySQL ne le fait pas. Pour obtenir MySQL pour diffuser le resultset, vous devez définir les paramètres suivants sur la déclaration:

pstmt = conn.prepareStatement(
     sql, 
     ResultSet.TYPE_FORWARD_ONLY, 
     ResultSet.CONCUR_READ_ONLY); 
    pstmt.setFetchSize(Integer.MIN_VALUE); 
0

La meilleure idée est de faire une sous requête et afficher 100 ou 1000 lignes à la fois/en une seule page. Et gérer la connexion par la mise en commun des connexions.

Pour créer une sous-requête, vous pouvez utiliser Nombre de lignes dans Oracle et Limite dans MY SQL.

0

permet de dire que nous avons une table qui contient 500 enregistrements dans ce

PreparedStatement stm=con.prepareStatement("select * from table"); 
stm.setFetchSize(100);// now each 100 records are loaded together from the database into the memory, 
// and since we have 500 5 server round trips will occur. 
ResultSet rs = stm.executeQuery(); 
rs.setFetchSize (50);//overrides the fetch size provided in the statements, 
//and the next trip to the database will fetch the records based on the new fetch size 
Questions connexes