每日學習20170405--使用slick對DB同步訪問

首先感受一下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))
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章