IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Servlets/JSP Java Discussion :

mise en cache des result set de grosses requêtes


Sujet :

Servlets/JSP Java

  1. #1
    Membre du Club Avatar de gaboo_bl
    Profil pro
    Inscrit en
    Août 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2006
    Messages : 67
    Points : 58
    Points
    58
    Par défaut mise en cache des result set de grosses requêtes
    Bonjour à tous,

    Je suis en train de travailler sur un intranet permettant de consulter des données métier depuis une base Oracle. Tout celà tourne sur tomcat/jdbc/spring/webwork. Quand j'exécute ma requête, je charge les lignes retournées dans un objet List qui est ensuite utilisé par une taglib pour l'affichage sous forme de tableau (extremecomponents), qui propose des filtres qu'il effectue sur le List.
    Tout çà fonctionne très bien, sauf que du coup à chaque fois que j'utilise un filtre du tableau, celui ci recharge la page, accède à la liste, fais son filtre et affiche le résultat. Hors certaines requêtes sont très complexe et longue à executer. Ce que je voudrais, c'est garder en mémoire cet objet List entre deux rechargement de la page, et faire un test du type "Si je trouve dans la requete HTTP un parametre de filtre de la table, je renvoie directement ma liste sauvegardée sans réinterroger la BD"

    Je suis un peu débutant dans ces technos, et je ne sais pas trop comment faire çà, pourriez vous me conseiller? J'avais pensé à garder ma liste en tant que variable de session, mais est ce que çà ne pourrait pas poser de problème de mémoire (les résultats peuvent être assez volumineux)?

    Comme je le disais je suis novice en Java, donc si je suis à la masse en train de chercher à réinventer la roue, n'hésitez pas à le dire non plus

    Merci d'avance.

  2. #2
    Membre expérimenté
    Avatar de zekey
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 036
    Points : 1 403
    Points
    1 403
    Par défaut
    Je n'ai pas tout compris (un petit exemple serait le bienvenu) mais grosso modo. C'est une mauvaise pratique de stocker des données lourdes en mémoire, principalement pour des raisons de gestion de la mémoire:
    300 utilisateurs qui ont chacun une liste dans la session de 2000 objets avec chaque objets qui fait 500 bytes --> 286 Mb c'est bof surtout si tu comptes que tes braves utilisateurs ne se déloguerons pas proprement (ie en fermant le navigateur) et que tes 300 sessions en deviendrons 600 au bout de 20 min.

    Le probleme des objets en session c'est la maintenance.

    Bref maintenant si tu peux réexpliquer ce que tu veux faire on peut essaye de trouver mieux. Il n'y aurait pas un mecanisme de flow dans webwork ?
    Steve Hostettler
    est ton ami(e) et le tag aussi.

  3. #3
    Membre du Club Avatar de gaboo_bl
    Profil pro
    Inscrit en
    Août 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2006
    Messages : 67
    Points : 58
    Points
    58
    Par défaut
    OK Je vais essayer de reformuler par étape.

    imaginons la page requete.action qui affiche une table html contenant des données récupérées dans la base avec une requête sql req1.
    Quand l'utilisateur demande la page requete.action, je vais executer req1, et stocker le résultat dans une liste. Cette liste est utilisée dans ma jsp comme source du tableau.

    Donc pour l'instant, à chaque fois que l'utilisateur demande requete.action, req1 est executée dans oracle.

    Le tableau extremecomponents contient un formulaire qui permet de naviguer dans les données (ex: limiter le nombre de resultat, trier, précédent suivant quand le nombre de données affichées est limité...). Et comme c'est un formulaire, à chaque action de l'utilisateur il fait un submit, et donc ma page requete.action est redemandé: req1 est executée dans Oracle.

    Ce que je voudrais c'est que quand l'utilisateur demande une première fois la requête, la Liste retournée soit conservée quelque part, et que s'il execute le submit du tableau, l'action retourne cette liste sauvegardée pour ne pas avoir à réexecuter req1.
    Par contre s'il réactualise la page, je réexecute la requête.

    En fait le principe çà serait pour chaque utilisateur, je sauvegarde le résultat de la dernière requête qu'il a lancé pour ne pas avoir à la réexecuter si l'utilisateur filtre dessus.

    Je ne sais pas si tu vois mieux ce que je veux dire. Si çà peux aider je poste quand même le code là ou j'en suis:

    classe d'accès à la base:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    package DBaccess;
    import java.util.List;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.core.RowMapperResultReader;
     
     
    public class DbUserListImpl implements DbUserList{
    	private JdbcTemplate jdbcTemplate;
     
    	public List getUserList(){
    		String sql = "SELECT username, nom, prenom, groupe, usergroup FROM intranet_users order by nom";
    		return jdbcTemplate.query(sql, new RowMapperResultReader(new UserListRowMapper()));
    	}
    	public void setJdbcTemplate(JdbcTemplate jdbcTemplate){
    		this.jdbcTemplate = jdbcTemplate;
    	}
    }
    classe UserListRowMapper utilisée ci dessus:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package DBaccess;
     
    import org.springframework.jdbc.core.RowMapper;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Map;
    import java.util.HashMap;
     
    public class UserListRowMapper implements RowMapper{
    	public Object mapRow(ResultSet rs, int index) throws SQLException{
    		Map user = new HashMap();
    		user.put("nom",rs.getString("nom"));
    		user.put("prenom",rs.getString("prenom"));
    		user.put("groupe",rs.getString("groupe"));
    		user.put("username",rs.getString("username"));
    		user.put("usergroup",rs.getString("usergroup"));
    		return user;
    	}
    }
    le code de l'action:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    package myproject.actions;
     
    import java.util.List;
     
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.core.io.ClassPathResource;
     
    import DBaccess.DbUserList;
     
    import com.opensymphony.xwork.ActionSupport;
     
    public class User extends ActionSupport {
    	private BeanFactory factory;
    	private List personnes;
    	private DbUserList dbUserList;
     
    	public String execute(){
    		factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
    		dbUserList = (DbUserList) factory.getBean("DbUserList");
    		personnes = dbUserList.getUserList();
    		return SUCCESS;
    	}
    	public List getUserList(){
    		return personnes;
    	}
    }
    et le code d'affichage (c'est en freemarker, pas en jsp:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    <#assign ec=JspTaglibs["/WEB-INF/extremecomponents.tld"]>
      <#global list=userList>
        <@ec.table 
      	items="list"
      	imagePath="images/table/compact/*.gif"
      	rowsDisplayed="30"
      	view="compact"
      	action="user.action"
      	width="90%"
      	>
      	<@ec.exportPdf 
               fileName="userlist.pdf" 
               tooltip="Export PDF" 
               headerColor="black" 
               headerBackgroundColor="#b6c2da" 
               headerTitle="Liste des utilisateurs"
               text="PDF"
               />
          <@ec.exportXls
               fileName="userlist.xls" 
               tooltip="Export Excel"
               text="XLS"
               />
      	<@ec.row>
      		<@ec.column property="username" />
      		<@ec.column property="nom" />
      		<@ec.column property="prenom" />
      		<@ec.column property="groupe" />
      		<@ec.column property="usergroup" />
      	</@ec.row>
      </@ec.table>

  4. #4
    Membre expérimenté
    Avatar de zekey
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 036
    Points : 1 403
    Points
    1 403
    Par défaut
    Et bien le fait de cliquer sur trié, page suivante etc doit forcément sauvegarder des paramètres dans la requête. Cela doit te permettre de pour faire un petit if ou mieux d'utiliser une action différente ou encore une DispatchActionSupport.

    Sinon tu fais le contraire il faut le parameter refresh dans la requeste pour forcer un refresh.
    Steve Hostettler
    est ton ami(e) et le tag aussi.

  5. #5
    Membre du Club Avatar de gaboo_bl
    Profil pro
    Inscrit en
    Août 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2006
    Messages : 67
    Points : 58
    Points
    58
    Par défaut
    Ca oui je suis OK, en fait ce qui me pose surtout problème c'est de conserver l'objet liste entre deux action. Ma question c'est comment la stocker? Comme je le disais j'ai pensé à une variable de session, mais est ce que c'est faisable et fiable? Y-a-t-il d'autres solutions envisageables?

  6. #6
    Membre du Club Avatar de gaboo_bl
    Profil pro
    Inscrit en
    Août 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2006
    Messages : 67
    Points : 58
    Points
    58
    Par défaut
    Bon je viens de tester avec HttpSession, çà fait bien ce que je veux, mais je suis obligé de le mettre dans le code de mon action, alors que je voudrais l'implémenter dans ma classe d'accés à la base. Cette partie étant gérée par spring je pense que je vais aller poser la question dans le sous forum spécifique. Merci pour tes réponses en tout cas.

  7. #7
    Membre expérimenté
    Avatar de zekey
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 036
    Points : 1 403
    Points
    1 403
    Par défaut
    Oula ce que tu me raconte la c'est du cache au niveau de la couche de donnée.
    Je suis pas sur que du point de vu archi ce soit bien mieux.
    Steve Hostettler
    est ton ami(e) et le tag aussi.

Discussions similaires

  1. [PERL] NET::LDAP : Mise en cache des requêtes
    Par ricomervin dans le forum Modules
    Réponses: 1
    Dernier message: 17/04/2007, 10h36
  2. [Dates] Mise en cache des pages
    Par Alex67 dans le forum Langage
    Réponses: 2
    Dernier message: 27/03/2007, 12h42
  3. Mise en cache des résultats SQL Server
    Par Ultiny dans le forum Accès aux données
    Réponses: 1
    Dernier message: 17/02/2007, 12h11
  4. Empêcher la mise en cache des images
    Par oranoutan dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 15/02/2006, 11h49
  5. cache des results de SELECT
    Par killy-kun dans le forum Requêtes
    Réponses: 4
    Dernier message: 21/07/2005, 12h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo