首先感受一下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))
}