sql >> Database teknologi >  >> RDS >> Mysql

Batchindlæg med tabel, der har mange kolonner ved hjælp af Anorm

Jeg vil gå med mulighed B. Jeg er ikke særlig bekendt med BatchSql siden sidst jeg tjekkede, udfører den bare en bådbelastning af forespørgsler i rækkefølge, hvilket er frygtelig langsomt. Jeg vil anbefale at samle alt i en enkelt forespørgsel. Det er lidt mere kedeligt, men meget hurtigere at udføre en enkelt forespørgsel med tusinde indsættelser end tusinde enkeltindsættelser.

Lad os for nemheds skyld sige, at du har Seq af

case class Test(val1: Int, val2: Option[Long], val3: Option[String])

Så kan du bygge din forespørgsel sådan her:

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()

Bemærkninger:

Du bliver nødt til at kontrollere at values er ikke-tom, før du fortsætter, da den ville generere en ugyldig SQL-sætning, hvis den var.

Afhængigt af hvor mange rækker og kolonner du indsætter, vil de token-parsere, der skabte den forberedte sætning, i sidste ende blive langsommere fra den store mængde tokens, der skal parses (og strengstørrelsen). Jeg har bemærket dette efter et par hundrede rækker med flere kolonner. Dette kan afbødes noget. Takket være Scala er et stærkt indtastet sprog, Int og Long udgør ingen trussel for SQL-injektion. Du kan forberede dine SQL-sætninger ved at bruge strenginterpolation/sammenkædning for netop disse kolonner og binde de usikre kolonner med NamedParameter normalt. Det ville skære ned på antallet af tokens, der skal parses.



  1. JCombobox-værdi hentes fra My Sql

  2. Hvordan kopierer man data fra en tabel til en anden ny tabel i MySQL?

  3. Opret tabel ved hjælp af datostemplet

  4. Filtrering af data med JDBC RowSet