Tôi sẽ chọn phương án B. Tôi không rành về BatchSql
vì lần trước tôi đã kiểm tra nó chỉ thực hiện một tải các truy vấn theo trình tự, điều này rất chậm. Tôi khuyên bạn nên tổng hợp mọi thứ vào một truy vấn duy nhất. Nó tẻ nhạt hơn một chút, nhưng nhanh hơn nhiều để thực hiện một truy vấn với một nghìn lần chèn hơn một nghìn lần chèn.
Để thuận tiện, giả sử bạn có Seq
trong số
case class Test(val1: Int, val2: Option[Long], val3: Option[String])
Sau đó, bạn có thể tạo truy vấn của mình như sau:
Các giá trị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()
Ghi chú:
Bạn sẽ phải kiểm tra các giá trị values
đó không được để trống trước khi tiếp tục, vì nó sẽ tạo ra một câu lệnh SQL không hợp lệ nếu có.
Tùy thuộc vào số lượng hàng và cột bạn đang chèn, cuối cùng trình phân tích cú pháp mã thông báo đã tạo câu lệnh chuẩn bị sẽ chậm lại từ số lượng mã thông báo tuyệt đối để phân tích cú pháp (và kích thước chuỗi). Tôi đã nhận thấy điều này sau vài trăm hàng với nhiều cột. Điều này có thể được giảm nhẹ phần nào. Nhờ Scala là một ngôn ngữ được đánh máy mạnh, Int
và Long
không gây ra mối đe dọa nào cho SQL injection. Bạn có thể chuẩn bị các câu lệnh SQL của mình bằng cách sử dụng nội suy / nối chuỗi chỉ cho các cột đó và liên kết các cột không an toàn với NamedParameter
thông thường. Điều đó sẽ cắt giảm số lượng mã thông báo cần được phân tích cú pháp.