首先感受一下slick ORM的语法
映射
private class ArticleTable(tag:Tag) extends Table[Article](tag, "article"){
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def title = column[String]("title")
def abstraction = column[String]("abstraction")
def author = column[String]("author")
def date = column[String]("date")
def detailUrl = column[String]("detail_url")
def imgUrl = column[String]("img_url")
override def * = (id, title, abstraction, author, date, detailUrl, imgUrl) <> ((Article.apply _).tupled,Article.unapply)
}
private val articles = TableQuery[ArticleTable]
这样一个表的映射和操作接口就准备好了。
插入数据
def insert(article: Article) = articles += article
查询数据
def findByLimit = articles.sortBy(_.id desc).take(4).result
def find(id:Long) = articles.filter(_.equals(id))
其中第一个查询包括了排序和limit,第二个查询包含了select。另外的join等语法都是有非常简单的支持方式。
执行语句
val list:Future[Seq[Article]] = db.run(findByLimit)
slick与DB之间的交互全部默认为异步执行,返回全是future类型。
问题
由于slick全部是异步执行(按道理说应该对同步查询有所支持,但是查遍了手册和示例代码,都没有找到),很多用到同步的地方会比较麻烦。比如在controller层,查询记录并展示需要这样写:
def articles = Action.async { implicit request =>
articleDal.list.map { articles =>
Ok(views.html.article.articles(articles.toList))
}
}
完全变成了一个异步行为。如果这里我们就需要同步的读取到数据库,然后进行模板渲染应该怎么做呢?
解决方法
增加一行阻塞代码:
val sychList:List[Article] = Await.result(list, Duration.Inf).toList
之后就又可以同步的读取数据库了:
def articles = Action{
Ok(views.html.article.articles(articleDal.sychList))
}