插入
本章描述如何向数据库插入记录。
插入单条记录
在Kronos中,我们可以使用KPojo.insert().execute()方法向数据库中插入一条记录。
val user: User = User(
id = 1,
name = "Kronos",
age = 18
)
user.insert().execute()自增主键和影响行数
execute() 返回 KronosOperationResult。
val user: User = User(
name = "Kronos",
age = 18
)
val result = user.insert().withId().execute()
val affectedRows = result.affectedRows
val lastInsertId = result.lastInsertId.withId() 表示本次插入需要读取数据库生成的 ID。目标 KPojo 需要使用自增主键。
更多用法见 📚生成的自增主键 ID。
批量插入记录
同一条 SQL 需要用多组参数执行时,见 📚批量操作。
INSERT SELECT
使用 KSelectable<Selected>.insert<Target>() 可以把查询结果插入目标表。没有显式 values 时,Kronos 会把来源 select 列表写入目标可插入字段。
kotlin
Order()
.select { [it.id, it.userId, it.status] }
.where { it.status == 1 }
.insert<OrderArchive>()
.execute()Mysql
INSERT INTO `order_archive` (`id`, `user_id`, `status`)
SELECT `id`, `user_id` AS `userId`, `status`
FROM `order`
WHERE `order`.`status` = :statusexecute() 返回 KronosOperationResult。对于 INSERT SELECT,affectedRows 是生成语句插入的行数。
result
val result = Order()
.select { [it.id, it.userId, it.status] }
.where { it.status == 1 }
.insert<OrderArchive>()
.execute()
val insertedRows = result.affectedRows没有显式 values 时,来源 select 列表需要匹配目标可插入字段数。
column count
Order()
.select { it.id }
.insert<OrderArchive>()
.build()error
Insert-select source column count (1) must match target insertable field count (3).当写入值来自来源表达式或标量子查询时,可以使用显式 values。
kotlin
Order()
.select { [it.id, it.userId, it.status] }
.where { it.status == 1 }
.insert<OrderArchive> {
[
it.id,
it.userId + 1,
Order()
.select { order -> order.status }
.where { order -> order.userId == 38 }
.limit(1)
]
}
.execute()Mysql
INSERT INTO `order_archive` (`id`, `user_id`, `status`)
SELECT `id`,
(`user_id` + 1),
(
SELECT `status`
FROM `order`
WHERE `order`.`user_id` = :userId
LIMIT 1
)
FROM `order`
WHERE `order`.`status` = :status来源也可以是派生 selectable。目标字段顺序仍来自目标 KPojo 的可插入字段。
derived source
val paidOrders = Order()
.where { it.status == 1 }
.select { [it.id, it.userId, it.status] }
.where { it.userId == 42 }
paidOrders
.insert<OrderArchive>()
.execute()Mysql
INSERT INTO `order_archive` (`id`, `user_id`, `status`)
SELECT `q`.`id`, `q`.`user_id` AS `userId`, `q`.`status`
FROM (
SELECT `id`, `user_id` AS `userId`, `status`
FROM `order`
WHERE `order`.`status` = :status
) AS `q`
WHERE `q`.`user_id` = :userId目标 KPojo 使用自增主键时,Kronos 会从目标字段列表排除该字段。
kotlin
Order()
.select { [it.userId, it.status] }
.where { it.status == 1 }
.insert<OrderIdentityArchive>()
.execute()Mysql
INSERT INTO `order_identity_archive` (`user_id`, `status`)
SELECT `user_id` AS `userId`, `status`
FROM `order`
WHERE `order`.`status` = :statusjoin source、union source、标量子查询规则和投影细节见 📚子查询。
指定使用的数据源
在Kronos中,我们可以将KronosDataSourceWrapper传入execute方法,以实现自定义的数据库连接。
val customWrapper = CustomWrapper()
val user: User = User(
id = 1,
name = "Kronos",
age = 18
)
user.insert().execute(customWrapper)