2012-11-27 9 views
5

Widzę, że anorm nie jest strukturą ORM, lecz wysyła dane bezpośrednio przez SQL. W przypadku większości aplikacji/stron internetowych nie należy za każdym razem wysyłać zapytania do bazy danych, musimy buforować dane za pomocą kodu SQL lub identyfikatora elementu. Zastanawiam się, czy Playframework dostarczył jakiegokolwiek mechanizmu buforowania? Jeśli nie, jak ją dodać?Jak dodać mechanizm pamięci podręcznej podczas korzystania z anormu w Playframework

Dzięki.

Odpowiedz

10

Można użyć cache Odtwórz w kontrolerze, zanim zapytań do bazy danych. Oto prosty przykład pochodzi od Play cache documentation i Scala API:

val user: User = Cache.getOrElse[User](key = "user" + userId, expiration = 10) { 
    User.findById(userId) 
} 

W tym kodzie, przed próbą zapytanie do bazy danych, wykonujemy odnośnika w pamięci podręcznej, aby sprawdzić, czy użytkownik nie został załadowany wcześniej. Jeśli nie zostanie znaleziony w pamięci podręcznej, przechowujemy go w pamięci podręcznej z wygaśnięciem w 10 sekund.

+0

+1, ale 10 sekund pamięci podręcznej? Chodziłem od 2 minut do 24 godzin osobiście. Nie jestem pewien, czy istnieje punkt malejących zwrotów przy ustawianiu bardzo niskiego czasu wygaśnięcia pamięci podręcznej. – virtualeyes

+0

Oczywiście, to było tylko na przykład. –

0

Zakładając, że korzystasz z platformy Play2, rzeczywiście zapewnia mechanizm pamięci podręcznej. Ma piękny dokumentację tutaj:

http://www.playframework.org/documentation/2.0/JavaCache (jego nazwie javacache, ale działa od Scala)

+0

Dzięki za odpowiedź. Widzę to z dokumentu odtwarzania, używa on ehcache, ale nie jest zintegrowany z anormem, nie jest łatwo użyć go do buforowania wyników zapytań. Zastanawiam się tylko, czy Playframework zapewnił sposób na zrobienie tego. Jeśli ktoś zaimplementował pamięć podręczną, pomoże to również w przypadku – Simon

6

Możesz po prostu buforować odpowiedź metod Anorm. Na przykład, że prawdziwa metoda używam:

def findById(id: Long): Option[User] = { 
    Cache.getOrElse(userCacheKey + id, 60*60) { 
     DB.withConnection { 
     implicit connection => 
      SQL("select * from publisher where id = {id}").on('id -> id).as(User.simple.singleOpt) 
     } 
    } 
} 

Kod robi Zaznacz i zapisuje odpowiedź w pamięci podręcznej poprzez getOrElse. Jeśli wartość znajduje się w pamięci podręcznej, zostanie zarchiwizowana, a zapytanie nie zostanie wykonane.

Jedynym problemem jest to, że podczas aktualizacji podmiotu Użytkownika musisz zaktualizować pamięć podręczną (więc nie zachować nieaktualne dane):

// Assumes a user: User object available with the updated user 
Cache.set(userCacheKey + id, cached.copy(name = user.name, avatar = user.avatar, bio = user.bio, url = user.url, location = user.location), 60*60) 
+0

Ta sama odpowiedź w tym samym czasie :-) –

+0

haha ​​tak, trochę inaczej, ponieważ przechowuję je w Anorm, ty w dzwoniącym, ale w zasadzie to samo :) –

+0

dziękuję, to podejście pracował, ale wymaga zbyt wiele kodowania i osadza się w kodzie biznesowym. Oczekuję, że mechanizm pamięci podręcznej powinien być wspólną strukturą, tak aby użytkownik końcowy dbał jedynie o logikę zapytania, ale nie o unieważnianie pamięci podręcznej i pamięci podręcznej. Będzie idealnie, jeśli anorm może to zrobić dla mnie :) – Simon