使用 QueryBuilder 插入数据
非官方测试版翻译
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
你可以使用 QueryBuilder 创建 INSERT 查询。
示例:
await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values([
{ firstName: "Timber", lastName: "Saw" },
{ firstName: "Phantom", lastName: "Lancer" },
])
.execute()
这是在性能方面最有效的向数据库中插入行的方法,你也可以用这种方式执行批量插入。
原生 SQL 支持
在某些情况下执行 SQL 查询时,需要使用函数式值:
await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values({
firstName: "Timber",
lastName: () => "CONCAT('S', 'A', 'W')",
})
.execute()
警告:使用原生 SQL 时,请确保正确清理值以防止 SQL 注入。
冲突时更新值
当插入值因现有数据产生冲突时,可使用 orUpdate 函数更新冲突目标的特定值。
await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values({
firstName: "Timber",
lastName: "Saw",
externalId: "abc123",
})
.orUpdate(["firstName", "lastName"], ["externalId"])
.execute()
带条件的冲突时更新值(Postgres、Oracle、MSSQL、SAP HANA)
await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values({
firstName: "Timber",
lastName: "Saw",
externalId: "abc123",
})
.orUpdate(["firstName", "lastName"], ["externalId"], {
overwriteCondition: {
where: {
firstName: Equal("Phantom"),
},
},
})
.execute()
插入时忽略错误(MySQL)或不执行操作(Postgres、Oracle、MSSQL、SAP HANA)
当插入值因现有数据或无效数据产生冲突时,使用 orIgnore 函数可抑制错误并仅插入有效数据行。
await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values({
firstName: "Timber",
lastName: "Saw",
externalId: "abc123",
})
.orIgnore()
.execute()
值未更改时跳过数据更新(Postgres、Oracle、MSSQL、SAP HANA)
await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values({
firstName: "Timber",
lastName: "Saw",
externalId: "abc123",
})
.orUpdate(["firstName", "lastName"], ["externalId"], {
skipUpdateIfNoValuesChanged: true,
})
.execute()
使用部分索引(Postgres)
await dataSource
.createQueryBuilder()
.insert()
.into(User)
.values({
firstName: "Timber",
lastName: "Saw",
externalId: "abc123",
})
.orUpdate(["firstName", "lastName"], ["externalId"], {
skipUpdateIfNoValuesChanged: true,
indexPredicate: "date > 2020-01-01",
})
.execute()
从 SELECT 查询插入数据
通过 valuesFromSelect() 方法配合 SELECT 查询,可将数据从一个表插入到另一个表。这会生成 INSERT INTO ... SELECT FROM 语句,适用于数据迁移、归档或在表之间复制数据。
直接使用 SelectQueryBuilder
// Create a select query to get the source data
const selectQuery = dataSource
.createQueryBuilder()
.select(["user.firstName", "user.lastName"])
.from(User, "user")
.where("user.isActive = :isActive", { isActive: true })
// Insert the selected data into another table
await dataSource
.createQueryBuilder()
.insert()
.into(ArchivedUser, ["firstName", "lastName"])
.valuesFromSelect(selectQuery)
.execute()
使用回调函数
也可通过回调函数构建 SELECT 查询:
await dataSource
.createQueryBuilder()
.insert()
.into(ArchivedUser, ["firstName", "lastName", "archivedAt"])
.valuesFromSelect((qb) =>
qb
.select(["user.firstName", "user.lastName", "NOW()"])
.from(User, "user")
.where("user.deletedAt IS NOT NULL"),
)
.execute()
使用连接(joins)
可在 SELECT 查询中使用连接(joins)来合并多个表的数据:
await dataSource
.createQueryBuilder()
.insert()
.into(UserReport, ["userName", "orderCount"])
.valuesFromSelect((qb) =>
qb
.select(["user.name", "COUNT(order.id)"])
.from(User, "user")
.leftJoin("user.orders", "order")
.groupBy("user.id"),
)
.execute()
注意: 使用
valuesFromSelect()时,实体监听器和订阅器(@BeforeInsert、@AfterInsert)不会被调用,因为在插入操作期间不会创建实体实例。
注意:
updateEntity选项在使用valuesFromSelect()时无效,因为没有实体实例可供更新。