我正在尝试在我的播放应用程序中进行缓存,看起来它正在运行,但代码似乎比我预期的更冗长,我会感谢任何关于简化的评论或我遗漏的东西。这个问题是this basic cache question的一个扩展。代码(在此处略显简化)如下:
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
}
}
编辑:在更新或插入Learner(在本例中)的任何位置设置缓存值非常重要。在insert上设置是必要的,否则插入之前的查询会将缓存设置为None,然后将来的getAs或getOrElse调用将返回None,即使现在存在一个值。
答案 0 :(得分:4)
你可以像这样使用getOrElse
方法:
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)
}
}
如果在内存中找到Option[Learner]
,则会立即返回expiration_time
,如果不是,则完成对DB的调用,并以过期时间{{1}}缓存结果。