2016-05-15 4 views
0

私はAnormと一緒にプレイ2を使用してデータベースアクセスを管理しています。私がやっている共通のパターンはこれです:自分自身を繰り返さずにクロージャからデータを渡す方法

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

を追加します。例えば ​​'DEF withCheckAndJob [T](F:(CheckType、JOBTYPE)=> T)よりもT = ???あり' – cchantep

答えて

1

タプル宣言を複製しない簡単な方法はありませんが、varは間違いなくそれを回避する方法ではありません。

タプルとして返された時刻に複数の変数があると、それが変わって難しくなることに言及しています。これは本当に面倒でエラーが発生しやすくなります。特に、同じパラメータ型の大きなNタプルを持つことになります。このシナリオでは、私は専用の、つまりを持つことを考慮します。ここでは、タプル内の位置ではなく名前で変数を参照できます。副次的な利点は、コンテナ全体を変数に割り当てて、それを自然な方法で参照できることです。

最後に、特定のユースケースについてはあまり言及していませんが、別のwithConnectionブロックで2つのクエリ結果を取得することを検討する価値はあるかもしれません。コレクション・プーリング・メカニズムを使用している場合は、接続ブロックと同じブロック内にあるメリットはほとんどなく、別々のブロックを使用すると、別々の接続を使用してDB問合せを並列化する柔軟性も得られます。

0

私が思いついた3つの方法があります。すぐに

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

戻りタプルが、私は、これは単純なコードとval秒の少数のためにOKだと思います。より複雑なコードとより多くの場合は、エラーが発生しやすくなります。val誰かが誤って割り当ての一方の側でタプルの要素の順序を変更し、データを間違ったvalに割り当てます(型の不一致の原因となる場合にのみコンパイラによって報告されます)。

使用匿名クラス

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

あなたはdbResult.posts代わりdbResult.usersusersposts変数を持ってしたい場合は、次のことができます。

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

関連する問題