批量操作

本章描述如何执行批量 SQL 语句。

用多组参数执行同一条 SQL

同一条 SQL 需要写入多行时,使用 SqlExecutor.batchExecute。它会创建 KronosAtomicBatchTask,并调用当前 KronosDataSourceWrapper.batchUpdate(...)。

kotlin

import com.kotlinorm.database.SqlExecutor

val affectedRows: IntArray = with(SqlExecutor) {
    wrapper.batchExecute(
        "UPDATE user SET name = :name WHERE id = :id",
        arrayOf(
            mapOf("name" to "Alice", "id" to 1),
            mapOf("name" to "Bob", "id" to 2)
        )
    )
}

SQL

UPDATE user SET name = :name WHERE id = :id

result

affectedRows == intArrayOf(1, 1)

数组中的每个 map 都会绑定到 SQL 中的命名参数。返回的 IntArray 是 JDBC driver 返回的逐行执行结果。

直接创建批量任务

需要传递操作类型等元数据,或代码已经在处理 wrapper task 时,可以直接使用 KronosAtomicBatchTask。

kotlin

import com.kotlinorm.beans.task.KronosAtomicBatchTask
import com.kotlinorm.enums.KOperationType

val task = KronosAtomicBatchTask(
    sql = "INSERT INTO user (name, age) VALUES (:name, :age)",
    paramMapArr = arrayOf(
        mapOf("name" to "Alice", "age" to 18),
        mapOf("name" to "Bob", "age" to 20)
    ),
    operationType = KOperationType.INSERT
)

val affectedRows = wrapper.batchUpdate(task)

SQL

INSERT INTO user (name, age) VALUES (:name, :age)

result

affectedRows == intArrayOf(1, 1)

KronosAtomicBatchTask.parsedArr() 会把命名参数 SQL 转成一条 JDBC SQL,并为每行生成一组 JDBC 参数。

kotlin

val (jdbcSql, jdbcParams) = task.parsedArr()

jdbcSql == "INSERT INTO user (name, age) VALUES (?, ?)"
jdbcParams.map { it.toList() } == listOf(
    listOf("Alice", 18),
    listOf("Bob", 20)
)

批量插入形态

批量插入使用同样的批量任务形态。保持固定列列表,并为每行传入一个参数 map。

kotlin

with(SqlExecutor) {
    wrapper.batchExecute(
        "INSERT INTO user (name, age) VALUES (:name, :age)",
        arrayOf(
            mapOf("name" to "Alice", "age" to 18),
            mapOf("name" to "Bob", "age" to 20)
        )
    )
}

单行 KPojo mutation DSL 见 📚插入、📚更新、📚删除 和 📚更新插入。