mars102009

Parcourir de gros volume de données en 2 lignes de code ?

un commentaire une annexe


dao-small.pngLorsque nous ne pouvons rien supposer du volume ou du nombre de résultat qu'une requête va nous retourner (hormis le seul fait que la mémoire vive ne sera pas du tout suffisante...), nous avons deux principales techniques pour faire en sorte que tout ce passe bien :

  • utiliser un chargement à la demande des différents objets, ce qui nécessite d'avoir une session ouverte pour toute la durée de traitement,
  • utiliser un mécanisme de pagination en suivant le pattern DAO sans garder de session.

C'est cette dernière technique que je vais utiliser ici. Cependant, un mécanisme de pagination classique a plusieurs inconvénients majeurs car:

  • il faut gérer la notion de page courante,
  • la navigation au sein des données à de gros impacts sur le code: il est tout de suite moins clair, moins évolutif, etc...
Je vous propose de capitaliser sur ce mécanisme, de rentre transparents la gestion de ces index et des différents appels à la source de données. 2 lignes de codes cotés clients, voilà ce que je vous propose de réaliser.

La théorie par la pratique

Imaginez:
  • un simple bean "CarBean" qui possède deux attributs "color" et "name",
  • une DAO "CarBeanDao" qui permet les opérations classiques d'enregistrement/suppression et deux méthodes "list" pour parcourir l'ensemble des voitures, et "find"pour lister uniquement celle qui possède un attribut spécifique.
  • une base de données possédant des milliers de milliers d'entité "CarBean"
Voici le diagramme de classe utilisé pour cet exemple:

SampleClassDiagram.jpg
Pour accéder à 10 ou 1000000 entités "CarBean", le code client sera toujours semblable à cela:

public void testCarBean() {
initializeData();
System.err.println("***************************************************");
System.err.println("Find all car ");
System.err.println("***************************************************");
for(CarBean car: m_carBeanDao.list())
System.err.println(car.getName());
System.err.println("***************************************************");
System.err.println("Find all car with a specified color");
System.err.println("***************************************************");
for(CarBean car: m_carBeanDao.find("blue"))
System.err.println(car.getName());
}
private void initializeData() {
for (int i = 0; i <= 22; i++)
m_carBeanDao.save(new CarBean("car " + i, "blue"));
for (int i = 0; i <= 23; i++)
m_carBeanDao.save(new CarBean("car " + i, "red"));
}

Personnellement, je n'ai pas encore trouvé plus simple qu'un " foreach "...

Tout le mécanisme est réalisé au niveau de la classe "CarBeanDao" en utilisant deux objets "ValueIterator" et "ValueHandler" dont voici un diagramme de classe:

ValueIteratorClassDiagram.jpg
"ValueHandler" est une interface qui définie une méthode qui va interroger la base de donnée à la demande.


"ValueIterator" est une sorte d'itérateur qui va gérer pour vous toute la problématique liée à la pagination, dont voici les deux principales méthodes:



L'implémentation au niveau de la DAO consiste à écrire un code java équivalent à ceci:


Vous vous occupez uniquement de créer votre requête de façon normale, sans les soucis de pagination...

Pour les curieux, voici un diagramme de séquence qui explicite de façon plus détaillée ce qui se passe lors de l'appel à la méthode "find" :

FindSequenceDiagram.jpg

Le projet

Je vous ai rassemblé toutes les sources nécessaires (les classes ValuesXXXX , les classes d'exemple et le test unitaire) dans un projet eclipse.
Ce projet est organisé comme suit:
utilityProject.jpg
Pour le tester vous devez mettre à jour le fichier "utility.properties" qui contient la chaîne de connexion à la base de données, et la classe path de façon à référencer les projets Spring, hibernate...


Si vous rencontrez des problèmes, ou avez des suggestions n'hésitez pas :-)


Par Jérôme Guibert, dans Technique
un commentaire

Envoyer à un ami 

une annexe

un commentaire

Jérôme Guibert

Jérôme Guibert

Le lundi 28 février 2011, 15:35

Bonjour,

Vous pouvez retrouver le code source associé à cet article sur https://code.google.com/p/blog-intelligents-ia/.

J'en ai profiter pour maveniser ce petit jar, et je souhaite très bientôt mettre à jour cet exemple notamment au sujet de la gestion des DAO, en utilisant JPA. :p

svn checkout http://blog-intelligents-ia.googlecode.com/svn/trunk/ blog-intelligents-ia-read-only
cd blog-intelligents-ia-read-only/dao-utility
mvn clean install

La classe de test utilise h2 comme base de données locale, pour faire tourner l'exemple vous avez juste a lancer les test unitaire avec votre ide favorie, ou:

mvn test

Bonne lecture

Ajouter un commentaire

Identité

S'abonner pour recevoir les commentaires suivants par email

Texte

Les commentaires peuvent être formatés en utilisant une syntaxe wiki simplifiée.

:) :(( :p X-( :x :-/ 0:) B-) &gt;-)