【问题标题】:Best practice for cache requests on persisted objects in Play/ScalaPlay/Scala 中持久对象缓存请求的最佳实践
【发布时间】:2014-04-23 14:20:26
【问题描述】:

我正在尝试在我的 play 应用程序中进行缓存,看起来它正在工作,但代码似乎比我预期的更冗长,我会感谢任何关于简化的 cmets 或我遗漏的东西。这个问题有点像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(在本例中)的任何位置设置缓存值非常重要。必须设置插入,否则插入之前的查询会将缓存设置为 None,然后未来的 getAs 或 getOrElse 调用将返回 None,即使现在存在值。

【问题讨论】:

    标签: scala caching playframework-2.2


    【解决方案1】:

    您可以像这样使用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

    【讨论】:

    • 太好了,这看起来很完美,谢谢。我实际上尝试过类似的东西,但我认为问题是我忘记在插入过程中清除缓存,所以它一直显示为无。还有关于过期时间的提示,虽然我不确定我会立即使用它。
    猜你喜欢
    • 2020-09-26
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    相关资源
    最近更新 更多