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

JDBC Java Discussion :

Mettre en cache JDBC


Sujet :

JDBC Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 139
    Par défaut Mettre en cache JDBC
    Bonjour,

    j'essaie de mettre en cache des résultats de requêtes SQL, histoire qu'elles soient exécutées moins souvent et que les perf de l'appli soient améliorées.

    Tous les accès aux BD sont faits avec JDBC, avec des preparedStatement. Aucun système de persistance est mis en place (c'est pourquoi je veux cacher).

    Bref, j'essaye d'utiliser EHCache qui apparemment fait bien son boulot dans ce domaine, mais étant débutant en JEE je rencontre quelques difficultés.

    Pour résumé, j'ai mes EJB dans un package dans un jar. J'ai créé un autre package dans ce même jar dans lequel j'ai mis les classes d'implémentation et d'interface de mes caches :
    -Cache.java (interface)
    -CacheImpl.java
    -CacheFactory.java
    -ehcache-config.xml


    Ça plante à la récupération du cache. J'utilise mon cache comme ça :

    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
    32
    33
    34
    35
    36
    37
    38
       public ArrayList<String> selectPart(String requete) throws Exception {
            PreparedStatement psSel = null;
            ResultSet rs = null;
            try {
                checkConnectionBDGdP();
     
                //initialisation du cache (une seule fois)
                if(cacheInit==false){
                    CacheFactory.init(Constantes.cachePATH);
                    sqlCachePart = CacheFactory.getCacheInstance("SqlCacheSelectPart");
                    cacheInit=true;
                }
     
     
                //on teste si le cache possède la liste recherchée
    /*
                if(sqlCachePart.get(requete)!=null){
                    return (ArrayList<String>) sqlCachePart.get(requete);
                }
                //sinon on fait le traitement
                else{
    */
                    psSel = connBDGdP.prepareStatement(Constantes.SELECT_QUERY);
                    psSel.setString(1, requete);
     
                    rs = psSel.executeQuery();
     
                    ArrayList<String> parts = new ArrayList<String>();
                    while(rs.next()) {
                        String partie = rs.getString(1);
                        parts.add(partie);
                    }
                    //on place le nouveau couple de valeur dans le cache
                 //   sqlCachePart.put(requete, parts);
     
                    return parts;
     
              //  }
    Mais le log de GlassFish me sort plein d'erreurs.. notamment ces lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Caused by: net.sf.ehcache.CacheException: Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
    1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
    2. Shutdown the earlier cacheManager before creating new one with same name.
    Donc comment utiliser correctement EHCache ?
    J'ai essayé d'initialiser directement le cache dans la méthode getCacheInstance mais là du coup ça me recréé autant de caches qu'il y a de requêtes..

    Des idées ?

    Merci !

  2. #2
    Membre Expert
    Avatar de fxrobin
    Homme Profil pro
    Architecte SI, Java Fan, API Manager
    Inscrit en
    Novembre 2007
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte SI, Java Fan, API Manager
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2007
    Messages : 875
    Par défaut
    la partie "init" tu devrais la faire dans la cache Factory et pas dans ta méthode.

    montre la factory que je te dise où mettre cette partie.

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 139
    Par défaut
    Voilà le CacheFactory :

    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
    public class CacheFactory
    {
        // instance du CacheManager de EHCache
        private static CacheManager cacheManager;
     
        public static void init(String pathToSetupFileOfEhCache)
        {
           cacheManager = new CacheManager(pathToSetupFileOfEhCache);
           System.out.println("|--- Using EHCache ");
           System.out.println("|--- configuration File :  ehcache-config.xml");
           System.out.println("|--- cache list :  ");
           for(String cacheName : cacheManager.getCacheNames())
           {
             System.out.println("|----- cache : "+cacheName);
           }
        }
     
        public static <K,V> Cache getCacheInstance(String cacheName)
        {
            if (cacheManager==null)
            {
              //init(Constantes.cachePATH);
              throw new RuntimeException("Cache pas initialisé. Utiliser la méthode init(String)");
            }
            else
            {
              return new CacheImpl <K,V> (cacheManager, cacheName);
            }
        }
    Je voulais mettre le init là où il est en com, mais si je fais ça GF me sort des milliers de lignes "Cache créé.." qui viennent du constructeur de CacheImpl

  4. #4
    Membre Expert
    Avatar de fxrobin
    Homme Profil pro
    Architecte SI, Java Fan, API Manager
    Inscrit en
    Novembre 2007
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte SI, Java Fan, API Manager
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2007
    Messages : 875
    Par défaut
    remontre CacheImpl


    sinon essaye déjà ça, qu'on optimisera plus tard :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public synchronized static <K,V> Cache getCacheInstance(String cacheName)
        {
            if (cacheManager==null)
            {
              init(Constantes.cachePATH);
              throw new RuntimeException("Cache pas initialisé. Utiliser la méthode init(String)");
            }
            else
            {
              return new CacheImpl <K,V> (cacheManager, cacheName);
            }
        }

    normalement tu ne dois pas appeler init ailleurs que dans cette méthode.

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 139
    Par défaut
    La voilà.
    Elle je n'y ai pas touché


    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    public class CacheImpl <K,V> implements cache.Cache <K,V> {
     
        net.sf.ehcache.Cache localCache = null;
        Class valueClass;
     
        public CacheImpl(CacheManager CM, String cacheName)
        {
            //URL url = getClass().getResource("ehcache.xml");
            CacheManager manager = CM;
            String name = "ImplCache_"+cacheName;        
            localCache = manager.getCache(cacheName);
            System.out.println("Cache créé : " + name);
        }
     
        public void putObject(K key, V value) {
            Element wrapperElement = new Element(key,value);
            localCache.put(wrapperElement);
            valueClass = value.getClass();
        }
     
        public V getObject(K key) {
            Element wrapperElement = localCache.get(key);
            return (V) wrapperElement.getObjectValue();
        }
     
        public String getValueClass() {
            return valueClass.getName();
        }
     
        /* méthodes imposées par l'interface Map */
     
        public int size() {
            return localCache.getSize();
        }
     
        public boolean isEmpty() {
            return localCache.getSize() == 0 ? true : false;
        }
     
        public boolean containsKey(Object key) {
            return localCache.isKeyInCache(key);
        }
     
        public boolean containsValue(Object value) {
            return localCache.isValueInCache(value);
        }
     
        public V get(Object key) {
            return this.getObject((K) key);
        }
     
        public V put(K key, V value) {
            this.putObject(key, value);
            return value;
        }
     
        public V remove(Object key) {
            V value = this.getObject((K) key);
            this.localCache.remove(key);
            return value;
        }
     
        public void putAll(Map<? extends K, ? extends V> m) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
     
        public void clear() {
            this.localCache.dispose();
        }
     
        public Set<K> keySet() {
            return new HashSet(this.localCache.getKeys());
        }
     
        public Collection<V> values() {
            List<V> list = new ArrayList<V>(this.size());
            Set<K> keys = this.keySet();
     
            for(K key : keys)
            {
                list.add(this.getObject(key));
            }
     
            return list;
        }
     
        public Set<Entry<K, V>> entrySet() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    /*
        public boolean exists(String r) {
            try{
                localCache.get(r);
                return true;
            }catch(Exception e){
                return false;
            }
        }
     * */
    }

  6. #6
    Membre Expert
    Avatar de fxrobin
    Homme Profil pro
    Architecte SI, Java Fan, API Manager
    Inscrit en
    Novembre 2007
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte SI, Java Fan, API Manager
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2007
    Messages : 875
    Par défaut
    tu as essayé le synchronized ?

    Normalement l'init ne doit se déclencher qu'une seule fois quand le cacheManager est null.


    peux tu aussi montrer ton fichier de configuration EHCACHE ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Performance] Solution pour mettre en cache l'application
    Par anthyme dans le forum Silverlight
    Réponses: 6
    Dernier message: 28/02/2008, 13h11
  2. Mettre en cache une requête sql
    Par mims1664 dans le forum Langage
    Réponses: 7
    Dernier message: 07/03/2007, 14h19
  3. Réponses: 15
    Dernier message: 15/10/2006, 20h34
  4. [Data] [Cache] Comment mettre en cache un objet ?
    Par Ho(c)ine. dans le forum Spring
    Réponses: 2
    Dernier message: 02/02/2006, 07h33
  5. Réponses: 2
    Dernier message: 27/09/2005, 12h46

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