Eu vou com a opção B. Não estou muito familiarizado com
BatchSql
desde a última vez que verifiquei, ele apenas executa uma carga de consultas em sequência, o que é muito lento. Eu recomendo agregar tudo em uma única consulta. É um pouco mais tedioso, mas muito mais rápido executar uma única consulta com mil inserções do que mil inserções únicas. Por conveniência, digamos que você tenha
Seq
do case class Test(val1: Int, val2: Option[Long], val3: Option[String])
Então você pode construir sua consulta assim:
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()
Observações:
Você terá que verificar se os
values
não está vazio antes de continuar, pois geraria uma instrução SQL inválida se estivesse. Dependendo de quantas linhas e colunas você está inserindo, eventualmente os analisadores de token que criaram a instrução preparada ficarão mais lentos devido à grande quantidade de tokens a serem analisados (e ao tamanho da string). Eu notei isso depois de algumas centenas de linhas com várias colunas. Isso pode ser um pouco mitigado. Graças ao Scala ser uma linguagem fortemente tipada,
Int
e Long
não representam ameaça para injeção de SQL. Você pode preparar suas instruções SQL usando interpolação/concatenação de strings apenas para essas colunas e vincular as colunas não seguras com NamedParameter
normalmente. Isso reduziria o número de tokens que precisam ser analisados.