2016-12-11 5 views
1

Предположим, что таблица table1 имеет три столбца col1, col2 и col3. Также предположим, что мне нужно обновить col1 на основе значения col2. Например, с помощью следующего оператора SQLОбновление нескольких строк в одной транзакции в Slick 3.1.x

update table1 set col1=111 where col2=222 

Давайте также сказать, что я должен обновить 1000 раз table1 и у меня есть сведения в следующем Seq:

case class Table1 (col1: Int, col2: Int, col3: Int) 
val list = Seq(Table1(111,222,333),Table1(111,333,444), ....) 

Какой самый лучший способ обновить 1000 строк в Slick 3.1.x? Можно ли запустить оператор партии с foreach?

val action = table1.foreach(....) 

ответ

3

Вы можете использовать DBIO.sequence, чтобы создать список действий для выполнения, что-то вроде этого:

db.run(DBIO.sequence(list.map(l => ???))) 

Вот более полный пример:

import scala.concurrent.Await 
import scala.concurrent.duration.Duration 
import slick.driver.H2Driver.api._ 


object main { 

    // The class and corresponding table 
    case class Thing (id: String, col1: Int, col2: Int) 
    class Things(tag: Tag) extends Table[Thing](tag, "things") { 
     def id = column[String]("id", O.PrimaryKey) 
     def col1 = column[Int]("col1") 
     def col2 = column[Int]("col2") 

     def * = (id, col1, col2) <> ((Thing.apply _).tupled, Thing.unapply) 
    } 

    val things = TableQuery[Things] 


    def main(args: Array[String]) { 

     val db = Database.forConfig("h2mem1") 

     try { 

      // Create schema 
      Await.result(db.run(things.schema.create), Duration.Inf) 

      // Insert some things for testing 
      Await.result(db.run(DBIO.seq(
       things += Thing("id4", 111, 111), 
       things += Thing("id5", 222, 222), 
       things += Thing("id6", 333, 333) 
      )), Duration.Inf) 

      // List of things to update 
      val list = Seq(Thing("id1", 111, 112), Thing("id2", 222, 223), Thing("id3", 333, 334)) 

      // ----- The part you care about is here ----- 
      // Create a list of Actions to update 
      val actions = DBIO.sequence(list.map(current => { 

       // Whatever it is you want to do here 
       things.filter(_.col1 === current.col1).update(current) 
      })) 

      // Run the actions 
      Await.result(db.run(actions), Duration.Inf).value 

      // Print out the results 
      val results = Await.result(db.run(things.result), Duration.Inf) 
      println(results) 


     } 
     finally db.close 
    } 
} 

Выход имеет обновленный col2:

Vector(Thing(id1,111,112), Thing(id2,222,223), Thing(id3,333,334)) 
+0

Спасибо. Может ли операция «DBIO.sequence» быть частью транзакции (т. Е. Использовать «транзакционно»)? – ps0604

+0

Да - это обычный 'DBIO'. Таким образом, вы можете, например, do 'Await.result (db.run (actions.transactionally), Duration.Inf) .value' –

Смежные вопросы