2016-01-23 36 views
5

başka bir tabloya bir sorgu sonucunu takma İstediğim sonucu elde etmek için. Sonunda ŞimdiScala + kaygan 3: Bu soru 3.0 ya da 3.1 <p></p> I <code>map</code>, <code>for</code>, vb işlem bir ara bir sorgu (bu konuda esnek değilim) yaklaşık kaygan

val foo: DBIOAction[Seq[MySchema.Bar], NoStream, Effect.Read] 

var ben bir val bar: TableQuery[MySchema.Bar] var ve o hesapta foo eklemek istiyorum.

Eğer foo bir Seq olsaydı bar ++= foo yapabilirdim, ama değil. Bulduğum tek yol, sonucunu beklemek suretiyle sonuçlandırmaktır. Bu

val query = (bar ++= Await.result(db.run(foo), Duration.Inf)) 

gibi Açıkçası querydb.run ile bir noktada çalıştırılması gerekiyor. Ama şimdi iki tane DB-çalışmam var. Herşeyi tek bir seferde yapmak daha iyi olmaz mıydı?

Bunu yapmanın daha iyi bir yolu var mı? ,

+0

'bar + = foo': Yani

yazabilir Tek bir sorgu içine böyle bir şey derlemek için? Ama yine de 'db.run' olsaydı ne olursa olsun '+ = 'veya' ++ = '... (?) – kornfridge

+0

Bence ++ = yan etkilerle slick2 api, slick3 iken daha işlevseldir, bu yüzden açıkça bir "db.run" – kornfridge

+0

yapmanizi gerektirir Evet, ++ = sonucu artık çalıştırılması gereken bir sorgu. Bu noktada soruyu düzenledim. Ama bu görev için iki tane db.run çağrısı yapmalıyım. – masgo

cevap

4

DBIOActionmap/flatMap işlevleri vardır, bu nedenle insertAction böyle tip DBIOAction[Int, NoStream, Effect.Write] falan olacak

val insertAction = foo.flatMap(bar ++= _) 

gibi bir şey yazabilirsiniz (Tamamen Int ve etkisi hakkında emin değilim) o zaman DB üzerindedb.run kullanarak çalıştırabilirsiniz; Daha sonra elde ettiğiniz şey, genel sorgu ve ekleme sonucunun geleceğidir.

+0

'flatMap' hile yapar. Sonunda çalıştırmam gereken tek bir DBIOAction kaldım. Bu konuyla başka bir şeye girdim: db.run() ne zaman yapmalıyım? İşte bir örnek 'val foo = db.run (persons.result.map (_. map {p => tr (td (p.id))})) 'Bunu böyle yapabilirim, ya da' db.run 'bölümünün sonunu verebilirim. '. Her iki yöntem de bana "Gelecek" in aynısını veriyor, performans açısından bir fark var mı? – masgo

+2

Genel olarak, 'DBIO' seviyesinde mümkün olduğunca çalışmak istersiniz; "db.run" sesini çağırdığınızda, kendi yürütme bağlamını kullanarak çok sayıda sorguya ihtiyaç duyulur ve size "Gelecek" i döndürür. Eğer slick, DB erişimine göre thread kullanımını optimize ederse, performansta potansiyel bir fark olduğunu düşünüyorum. –

1

Sorular çoktan cevaplandırıldı ancak buraya farklı bir çözüm aramaya geldim, bu yüzden başkalarına da yardımcı olabilir.

@Aldo'ın dediği gibi, DBIO seviyesinde mümkün olduğunca çalışmak istiyoruz, ancak daha ileri gidip tek bir sql deyim için derlediğimizden Query seviyesinde çalışmanız gerektiğini söyleyebilirim. veritabanına gönderilebilir. Örneğin, bir seçenekten bir ekleme INSERT INTO table1 SELECT...'a derlenmelidir. Eğer önerildiği gibi, flatMap kullanarak birden fazla DBIOS kullanırsanız, bu bir SELECT içine derlenecek, değerler belleğe getirilecek ve daha sonra INSERT ifadesi derlenecek, bir dizgede değerlerin enterpolasyonu yapılacak ve bu yeni sorgu gönderilecektir. veri tabanı. Gerçekte bu, seçiminiz birçok sonuç döndürdüğünde çok daha yavaş olabilir ve en kötü durumda belleğinizi boşaltabilir.

val bar: TableQuery[MySchema.Bar] 

val foo: Query[MySchema.Bar, Bar, Seq] 

val insert: DBIO[Int] = bar.forceInsertAll(foo)