Pójdę z opcją B. Nie jestem za bardzo zaznajomiony z BatchSql
odkąd ostatnio sprawdzałem, po prostu wykonuje szereg zapytań z łodzi, co jest strasznie powolne. Zalecam agregowanie wszystkiego w jedno zapytanie. Wykonanie pojedynczego zapytania z tysiącem wstawek jest nieco bardziej żmudne, ale znacznie szybsze.
Dla wygody załóżmy, że masz Seq
z
case class Test(val1: Int, val2: Option[Long], val3: Option[String])
Następnie możesz zbudować zapytanie w ten sposób:
val values: Seq[Test] = Seq(....)
/* Index your sequence for later, to map to inserts and parameters alike */
val indexedValues = values.zipWithIndex
/* Create the portion of the insert statement with placeholders, each with a unique index */
val rows = indexValues.map{ case (value, i) =>
s"({val1_${i}}, {val2_${i}}, {val3_${i}})"
}.mkString(",")
/* Create the NamedParameters for each `value` in the sequence, each with their unique index in the token, and flatten them together */
val parameters = indexedValues.flatMap{ case(value, i) =>
Seq(
NamedParameter(s"val1_${i}" -> value.val1),
NamedParameter(s"val2_${i}" -> value.val2),
NamedParameter(s"val3_${i}" -> value.val3)
)
}
/* Execute the insert statement, applying the aggregated parameters */
SQL("INSERT INTO table1 (col1, col2, col3) VALUES " + rows)
.on(parameters: _ *)
.executeInsert()
Uwagi:
Musisz sprawdzić, czy values
nie jest pusta przed kontynuowaniem, ponieważ gdyby tak było, wygenerowałoby nieprawidłową instrukcję SQL.
W zależności od tego, ile wierszy i kolumn wstawiasz, w końcu parsery tokenów, które utworzyły przygotowaną instrukcję, zwolnią z samej liczby tokenów do przeanalizowania (i rozmiaru ciągu). Zauważyłem to po kilkuset wierszach z kilkoma kolumnami. Można to nieco złagodzić. Dzięki temu, że Scala jest językiem silnie typizowanym, Int
i Long
nie stanowią zagrożenia dla wstrzyknięcia SQL. Możesz przygotować swoje instrukcje SQL za pomocą interpolacji/konkatenacji ciągów tylko dla tych kolumn i powiązać niebezpieczne kolumny za pomocą NamedParameter
normalnie. Zmniejszyłoby to liczbę tokenów, które należy przeanalizować.