Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add cache mechanism when using anorm in Playframework

I see anorm is not a ORM framework, it is querying data directly by SQL. For most of the application/website, we should not query the database everytime, we needs to cache the data either by SQL or item id. I wonder whether playframework has provided any kind of caching mechanism? If not how to add it?

Thanks.

like image 772
Simon Avatar asked Nov 27 '12 06:11

Simon


2 Answers

You can use the Play cache in your controller, before querying your database. Here is a straightforward example derived from the Play cache documentation and the Scala API:

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

In this code, before trying to query the database, we make a lookup in the cache to check if the User has not been loaded previously. If not found in the cache, we store it in the cache with an expiration in 10 seconds.

like image 181
ndeverge Avatar answered Oct 11 '22 15:10

ndeverge


You can simply cache the answer of the Anorm methods. For example, real method that I use:

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

The code does the Select and stores the answer in the cache via getOrElse. If the value is in the Cache, it will ber etrieved and no query will be executed.

The only issue is that when you update the entity User you'll have to update the cache (so it doesn't keep stale data):

// 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)
like image 39
Pere Villega Avatar answered Oct 11 '22 13:10

Pere Villega