Compojure + clojure.contrib.sql: запрос SELECT кэшируется. Зачем? - PullRequest
4 голосов
/ 02 июля 2010

Я пишу приложение Compojure TODO и MySQL в качестве основного хранилища данных.Я использую clojure.contrib.sql для взаимодействия с MySQL следующим образом:

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

Запросы, которые я использую, похоже, работают, однако результаты выглядят кэшированными.Например, после запуска

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

значение успешно вставлено в базу данных.Однако

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

возвращает одно и то же значение независимо от того, сколько элементов вставлено.Конечно, если я перезапущу веб-приложение, результаты будут обновлены, но это не очень удобно для производства:).

Есть идеи, почему это происходит?Заранее спасибо.

По запросу, здесь находится форма верхнего уровня для запроса SELECT:

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

1 Ответ

3 голосов
/ 07 июля 2010

Из последнего добавленного комментария к ответу вместе с последним обновлением текста вопроса я понимаю, что проблема не в том, что касается clojure.contrib.sql, а в форме defroutes.

(defroutes todo (GET "/" [] home-view)) означает, что запросы, соответствующие этому маршруту, получат home-view в качестве ответа. Теперь home-view оценивается только один раз, когда оценивается форма (def home-view ...) - и, в частности, связанный SQL-запрос выполняется только один раз.

Чтобы это исправить, переписайте home-view как функцию и вызовите ее по маршруту, возможно, так:

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

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

Тогда home-view -функция будет вызываться каждый раз, когда запускается маршрут (и выполнять свой SQL-запрос один раз для каждого такого вызова).

...