2016-05-15 29 views
0

我使用Play 2與Anorm管理數據庫訪問。我發現自己正在做的一個常見模式是:如何從閉包傳遞數據而不重複自己

val (futureChecklists, jobsLookup) = 
    DB.withConnection { implicit connection => 

    val futureChecklists = futureChecklistRepository.getAllHavingActiveTemplateAndNonNullNextRunDate() 

    val jobsLookup = futureChecklistJobRepository.getAllHavingActiveTemplateAndNonNullNextRunDate() 
     .groupBy(_.futureChecklist.id) 
     .withDefaultValue(List.empty) 

    (futureChecklists, jobsLookup) 

    } 

這似乎有點奇怪,因爲我必須重複自己。如果我在外部示波器中需要幾個變量,它也會變得不穩定,但我不想保持連接處於打開狀態。

是否有一種簡單的方法可以將此信息傳回而不必訴諸於var

我想什麼是一樣的東西:

val futureChecklists 
val jobsLookup 

DB.withConnection { implicit connection => 

    futureChecklists = futureChecklistRepository.getAllHavingActiveTemplateAndNonNullNextRunDate() 

    jobsLookup = futureChecklistJobRepository.getAllHavingActiveTemplateAndNonNullNextRunDate() 
     .groupBy(_.futureChecklist.id) 
     .withDefaultValue(List.empty) 

} 

這樣,我不必在開始和結束時相同的元組。

+0

我認爲這可能是有用的,如果你可以顯示你想達到的僞代碼。 – TeWu

+0

@TeWu當然,我會添加一些 – cdmckay

+0

您可以使用自定義貸款模式。例如,使用CheckAndJob [T](f:(CheckType,JobType)=> T)來確定:T =' – cchantep

回答

1

恐怕沒有簡單的方法不要複製元組聲明,但var絕對不是解決它的方法。

你提到,它變得奇怪和困難與多元變量時返回作爲元組。這確實可能變得非常棘手並且容易出錯,特別是當你最終得到具有相同參數類型的大N元組時。在這種情況下,我會考慮擁有一個專用的,即case class,您可以通過名稱而不是元組中的位置來引用變量。副作用是您可以將整個容器分配給一個變量並以自然的方式引用它。

最後但並非最不重要的是你沒有提及你的特定用例,但也許值得考慮在單獨的withConnection塊中獲得2個查詢結果。如果您正在使用任何集合池機制,那麼幾乎沒有任何好處將其與連接塊和獨立塊相同,您甚至可以靈活地使用單獨的連接對數據庫查詢進行旁路處理。

0

有,我想出了三種方式:

返回元組立即

val (users, posts) = 
    DB.withConnection { connection => (
    connection.getUsers, 
    connection.getPosts 
)} 

我覺得這是簡單的代碼和val的小號碼確定。對於更復雜的代碼和更多val s,這可能容易出錯。有人可能會意外地在賦值的一側改變元組的順序,並將數據分配給錯誤val(只有在編譯器也會導致類型不匹配時纔會報告它)。

使用匿名類

val dbResult = 
    DB.withConnection { connection => 
    new { 
     val users = connection.getUsers 
     val posts = connection.getPosts 
    } 
    } 

如果你喜歡usersposts變量而不是dbResult.usersdbResult.posts您可以:

import dbResult._ 

該解決方案是有點異國情調,但它工作得很好而且很乾淨。

用例類

首先定義測試用例類爲您的返回值:

case class DBResult(users: List[User], posts: List[Post]) 

,然後使用它:

val DBResult(users: List[User], posts: List[Post]) = 
    DB.withConnection { connection => 
    DBResult(
       users = connection.getUsers, 
       posts = connection.getPosts 
      ) 
    } 

這是最好的,如果你打算重用這個案例類多次。

+0

還有更多的方法。 PS:匿名類比我那裏的元組差。 – cchantep