Insert
This chapter describes how to insert records into the database.
Insert a single record
In Kronos, we can use the KPojo.insert().execute() method to insert a record into the database.
val user: User = User(
id = 1,
name = "Kronos",
age = 18
)
user.insert().execute()Last insert ID and affected rows
execute() returns a KronosOperationResult.
val user: User = User(
name = "Kronos",
age = 18
)
val result = user.insert().withId().execute()
val affectedRows = result.affectedRows
val lastInsertId = result.lastInsertId.withId() declares that this insert should read the generated ID. The target KPojo needs an identity primary key.
Read more about 📚generated identity IDs.
Batch insert records
Use 📚Batch Operations when the same SQL insert should run with many parameter sets.
INSERT SELECT
Use KSelectable<Selected>.insert<Target>() to insert rows from a query. Without explicit values, Kronos inserts the source select list into the target insertable fields.
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() returns KronosOperationResult. For INSERT SELECT, affectedRows is the number of rows inserted by the generated statement.
result
val result = Order()
.select { [it.id, it.userId, it.status] }
.where { it.status == 1 }
.insert<OrderArchive>()
.execute()
val insertedRows = result.affectedRowsThe source select list must match the target insertable field count when no explicit values are provided.
column count
Order()
.select { it.id }
.insert<OrderArchive>()
.build()error
Insert-select source column count (1) must match target insertable field count (3).Use explicit values when inserted values come from source expressions or scalar subqueries.
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` = :statusThe source can also be a derived selectable. The target field order still comes from the target KPojo insertable fields.
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` = :userIdWhen the target KPojo uses an identity primary key, Kronos excludes that field from the target field list.
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` = :statusFor join sources, union sources, scalar subquery rules, and projection details, see 📚Subqueries.
Specify the data source to use
In Kronos, we can pass KronosDataSourceWrapper into the execute method to achieve a custom database connection.
val customWrapper = CustomWrapper()
val user: User = User(
id = 1,
name = "Kronos",
age = 18
)
user.insert().execute(customWrapper)