2012-11-27 6 views
5

Vedo che anorm non è un framework ORM, sta interrogando i dati direttamente da SQL. Per la maggior parte delle applicazioni/siti Web, non dovremmo interrogare il database ogni volta, abbiamo bisogno di memorizzare nella cache i dati tramite SQL o ID oggetto. Mi chiedo se i playframework abbiano fornito alcun tipo di meccanismo di memorizzazione nella cache? Se non come aggiungerlo?Come aggiungere il meccanismo di cache quando si utilizza anorm in Playframework

Grazie.

risposta

10

È possibile utilizzare la cache di gioco nel controller, prima di interrogare il database. Ecco un esempio semplice derivato dalla Play cache documentation e la Scala API:

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

In questo codice, prima di tentare di interrogare il database, facciamo una ricerca nella cache per controllare se l'utente non è stato caricato in precedenza. Se non viene trovato nella cache, lo memorizziamo nella cache con una scadenza di 10 secondi.

+0

+1, ma 10 secondi di cache? Sto andando personalmente da 2 minuti a 24 ore. Non sono sicuro se ci sia un punto di rendimenti decrescenti nell'impostare tempi di scadenza della cache molto bassi. – virtualeyes

+0

Certo, era solo per l'esempio –

0

Supponendo che si stia utilizzando il framework Play2, fornisce effettivamente un meccanismo di cache. Ha buona documentazione qui:

http://www.playframework.org/documentation/2.0/JavaCache (la sua chiamata javacache, ma funziona da Scala)

+0

Grazie per la risposta. Lo vedo dal documento di gioco, sta usando ehcache, ma non è integrato con anorm, non è facile usarlo per memorizzare i risultati della query, mi chiedo solo se Playframework abbia fornito un modo per farlo. Se qualcuno ha implementato la cache, aiuterà anche – Simon

6

È possibile memorizzare nella cache la risposta dei metodi Anorm. Ad esempio, vero e proprio metodo che uso:

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) 
     } 
    } 
} 

Il codice fa il Select e memorizza la risposta nella cache via getOrElse. Se il valore si trova nella cache, verrà eliminato e non verrà eseguita alcuna query.

L'unico problema è che quando si aggiorna l'Utente entità dovrete aggiornare la cache (in modo da non tenere dati non aggiornati):

// 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

La stessa risposta allo stesso tempo :-) –

+0

haha ​​sì, leggermente diverso mentre lo memorizzo in Anorm, tu nel chiamante, ma essenzialmente lo stesso :) –

+0

grazie ragazzi, questo approccio ha funzionato, ma richiede troppa codifica e si integra nel codice aziendale. Prevedo che il meccanismo della cache dovrebbe essere un framework comune in modo che l'utente finale si preoccupi solo della logica della query, ma non della cache e dell'invalidazione della cache. Sarà perfetto se anorm può farlo per me :) – Simon