Pergunta

I am trying out caching in my play app, and it looks like it is working, but the code seems more verbose than I expected, and I'd appreciate any comments on simplification or something that I am missing. This question is a bit of an extension to this basic cache question. The code (slightly simplified for presentation here) is as follows:

def findById(id: Int): Option[Learner] = {
  Cache.getAs[Learner]("learner." + id) match {
    case None => DB.withConnection { implicit c => //-- no cache, read DB
      SQL("select * from learner where id={id}")
        .on('id -> id)
        .as(learnerP.singleOpt) match {
        case Some(learner) => { //-- found, set cache
          Cache.set("learner." + learner.id, learner)
          Some(learner)
        }
        case _ => None //-- no find in DB, do not set cache
      }
    }
    case Some(learner) => Some(learner) //-- return value in cache
  }
}

Edit: It's important to set the cache values anywhere that Learner (in this case) is updated or inserted. Setting on insert is necessary, otherwise a query prior to the insert will set the cache to None, and then future getAs or getOrElse calls will return None, even though a value now exists.

Foi útil?

Solução

You could use the getOrElse method like this:

Cache.getOrElse[Option[Learner]]("learner." + id, expiration_time) {
   DB.withConnection { implicit c => //-- no cache, read DB
      SQL("select * from learner where id={id}")
        .on('id -> id)
        .as(learnerP.singleOpt)
   }
}

If the Option[Learner] is found in memory, it is returned immediately, if it isn't, the call to DB is done and the result is cached with an expiration time expiration_time.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top