5

私は Squeryl を学んでおり、'using' 構文を理解しようとしていますが、ドキュメントが見つかりません。

次の例では、2 つのデータベースが作成されます。A にはHelloという単語が含まれ、B にはGoodbyeが含まれます。その意図は、A の内容を照会し、Worldという単語を追加して、結果を B に書き込むことです。

予想されるコンソール出力はInserted Message(2,HelloWorld)です

object Test {
    def main(args: Array[String]) {
        Class.forName("org.h2.Driver");
        import Library._

        val sessionA = Session.create(DriverManager.getConnection(
                "jdbc:h2:file:data/dbA","sa","password"),new H2Adapter)
        val sessionB = Session.create(DriverManager.getConnection(
                "jdbc:h2:file:data/dbB","sa","password"),new H2Adapter)

        using(sessionA){
            drop; create
            myTable.insert(Message(0,"Hello"))
        }
        using(sessionB){
            drop; create
            myTable.insert(Message(0,"Goodbye"))
        }

        using(sessionA){
            val results = from(myTable)(s => select(s))//.toList

            using(sessionB){
                results.foreach(m => {
                    val newMsg = m.copy(msg = (m.msg+"World"))
                    myTable.insert(newMsg)
                    println("Inserted "+newMsg)
                })
            }
        }
    }

    case class Message(val id: Long, val msg: String) extends KeyedEntity[Long]
    object Library extends Schema { val myTable = table[Message] }
}

現状では、 toListがval 結果行の最後に追加されていない限り、コードはInserted Message(2,GoodbyeWorld)を出力します。

using(sessionB)内で評価された場合でも、結果クエリをバインドしてsessionAを使用する方法はありますか? これは、toListを使用して、クエリに内容を評価させてメモリに保存させるよりも望ましいようです。

アップデート

Dave Whittaker の回答のおかげで、次のスニペットは「toList」に頼らずにそれを修正し、「使用」とクエリの実行の両方についての私の理解を修正します。

val results = from(myTable)(s => select(s))

using(sessionA){            
    results.foreach(m => {
        val newMsg = m.copy(msg = (m.msg+"World"))
        using(sessionB){myTable.insert(newMsg)}
        println("Inserted "+newMsg)
    })
}
4

1 に答える 1

3

まず、ドキュメントの不足についてお詫び申し上げます。using() コンストラクトは、SNAPSHOT ビルドでのみ使用できる新しい機能です。昨日、アーリー アダプター向けのドキュメントの問題について Max と実際に話しましたが、現在、それらの修正に取り組んでいます。

特定のセッションをクエリにバインドする方法は考えられません。あなたの例を見ると、トランザクションを反転させるのが簡単な回避策のようです。クエリを作成するとき、Squeryl は実際に DB にアクセスするのではなく、実行する SQL を表す AST を作成するだけなので、その時点で using(sessionA) を発行する必要はありません。次に、結果を反復処理する準備ができたら、using(sessionB) 内にネストされた using(sessionA) でクエリ呼び出しをラップできます。それは理にかなっていますか?

于 2011-12-06T15:48:42.507 に答える