2009-07-28 10 views
1

J'ai besoin de récupérer plusieurs enregistrements d'un SGBDR en Java (10-20k) mon système cible s'attend à ce qu'ils soient disponibles en tant que liste Java. Je veux donc implémenter mon code en tant que "liste virtuelle" où je ne récupère réellement que les enregistrements dont j'ai vraiment besoin. Je pense SQL commeImplémentation d'une liste virtuelle en Java

SELECT * FROM CLIENT PAYS OÙ = "Moldovia"

comme paramètre et juste retour ce qui est demandé. Très probablement, les données sont demandées par lots de 50. Des conseils sur la façon de faire cela?

Répondre

2

À moins que vous n'attendiez que vos clients accèdent aléatoirement aux données, il vaut probablement mieux retourner un Iterator. De plus, jetez un oeil à ResultSet.setFetchSize: http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html#setFetchSize(int)

donc quelque chose comme:

import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.util.Iterator; 

public class FooResultSetIterator implements Iterator<Foo> 
{ 
    private final ResultSet resultSet; 
    private boolean hasNext; 

    FooResultSetIterator(final ResultSet resultSet, final int fetchSize) throws SQLException 
    { 
    this.resultSet = resultSet; 
    this.resultSet.setFetchSize(fetchSize); 
    this.hasNext = resultSet.next(); 
    } 

    @Override 
    public boolean hasNext() 
    { 
    return hasNext; 
    } 

    @Override 
    public Foo next() 
    { 
    final Foo foo = new Foo(resultSet); 
    try 
    { 
     this.hasNext = resultSet.next(); 
    } 
    catch (final SQLException e) 
    { 
     throw new RuntimeException(e); 
    } 
    return foo; 
    } 

    @Override 
    public void remove() 
    { 
    throw new UnsupportedOperationException("Cannot remove items from a ResultSetIterator"); 
    } 

} 

class Foo 
{ 
    public Foo(ResultSet resultSet) 
    { 
    // TODO Auto-generated constructor stub 
    } 
} 
+0

Salut Simon, merci pour la réponse. J'ai besoin de faire une liste. L'autre système l'exige, mais bien sûr, une liste a un itérateur. Fondamentalement, les résultats seront visualisés dans un tableau de 50 entrées à la fois et un utilisateur peut sauter à n'importe quelle page. J'ai donc besoin de la taille totale pour que le navigateur de pagination puisse être rendu correctement – stwissel

1

Utilisez OFFSET et LIMIT dans votre requête:

SELECT * FROM CLIENT OU PAYS = "Moldovia" LIMITE 50 OFFSET 50

En supposant bien sûr que votre dialecte SQL permet. L'exemple retournera les lignes 51-100.

+0

Salut Vinay, je pensais à ça. Où je suis resté bloqué: la propriété List.size doit renvoyer le nombre total d'entrées. Donc j'aurais 2 requêtes - avec LIMIT & OFFSET et une avec COUNT (*) ... ou auriez-vous quelque chose de plus efficace? – stwissel

+0

Non, c'est ce que vous devez faire. –