2010-07-01 22 views
4

J'écris une application Compojure TODO et avec MySQL comme magasin de données principal. J'utilise clojure.contrib.sql pour l'interface avec MySQL comme suit:Compojure + clojure.contrib.sql: La requête SELECT est mise en cache. Pourquoi?

(def db {:classname "com.mysql.jdbc.Driver" 
     :subprotocol "mysql" 
     :subname "//localhost:3306/todo" 
     :user "<user>" 
     :password ""}) 

Les requêtes que je utilise semblent fonctionner, mais les résultats semblent être mis en cache. Par exemple, après avoir exécuté

(with-connection db 
    (insert-values :todos 
    [:name] [name])) 

la valeur est insérée avec succès dans la base de données. Toutefois,

(defn sql-query [query] 
    (with-connection db 
    (with-query-results rows [query] 
     (into [] rows)))) 

renvoie la même valeur, quel que soit le nombre d'éléments insérés. Bien sûr, si je redémarre l'application web, les résultats sont mis à jour, mais cela ne semble pas très productif :).

Une idée pourquoi cela se passerait-il? Merci d'avance.

Comme demandé, voici le formulaire de niveau supérieur pour la requête SELECT:

(def home-view 
    (render 
    (base {:title "Clojure Todo" 
      :content (apply str 
      (map #(% :name) 
       (sql-query "select * from todos")))}))) 
+0

Cela ressemble à la façon dont SQL Server met en cache des plans d'exécution pour les requêtes exécutées dans le but d'améliorer les performances de la base de données, empêchant ainsi l'optimisation des requêtes à chaque exécution. –

+0

Jetez un oeil à cet article pour en savoir plus sur la mise en cache des requêtes dans MySQL: http://www.databasejournal.com/features/mysql/article.php/3110171/MySQLs-Query-Cache.htm Cela pourrait bien être la cause. BTW, la chose en cache est l'ensemble de résultats réels; La mise en cache du plan d'exécution n'aurait aucun impact sur l'exactitude des résultats renvoyés. –

+0

Je ne pense pas que cela ait quelque chose à voir avec MySQL, je pense que c'est un problème de Clojure. –

Répondre

3

Depuis le commentaire le plus récemment ajouté sur la réponse en même temps que la mise à jour la plus récente du texte de la question, je crois que le problème n'a rien à voir avec clojure.contrib.sql, c'est avec le formulaire defroutes.

(defroutes todo (GET "/" [] home-view)) signifie que les demandes correspondant à cette route recevront home-view comme réponse. Maintenant, home-view est évalué une seule fois, lorsque le formulaire (def home-view ...) est évalué - et en particulier, la requête SQL associée est exécutée une seule fois.

Pour résoudre ce problème, réécrire home-view en fonction et avoir la route appeler, peut-être comme ceci:

(defn home-view [] 
    ...the render form from your old (def home-view ...) form goes here... 
) 

(defroutes todo (GET "/" [] (home-view))) 

Ensuite home-view -la fonction sera appelée à chaque fois que la route se déclenche (et exécuter son Requête SQL une fois pour chaque appel de ce type).

+0

Vous l'avez cloué. Merci de votre aide! –