Prisma ORM如何获取插入行自增ID?createMany为何仅返回受影响行数
Prisma获取插入记录自增ID的方法及createMany返回值设计说明
单条插入场景
单条插入直接使用create()方法即可,该方法默认返回包含自增主键在内的完整新记录对象,直接读取对应ID字段就能拿到和原生mysql_insert_id()等价的结果,不需要额外操作。
示例代码:
// 单条插入用户记录 const newRecord = await prisma.user.create({ data: { username: "test_user", age: 25 } }) // 直接获取刚生成的自增ID const lastInsertId = newRecord.id
批量插入场景
createMany()方法默认仅返回count字段标识受影响的行数,不会直接返回插入记录的自增ID,可根据自身环境选择对应方案获取ID:
- 若使用Prisma 4.6.0及以上版本、且数据库为MySQL 8.0.20及以上版本,可在调用时传入
returning参数指定需要返回的字段,即可拿到所有插入记录的自增ID:
const batchInsertResult = await prisma.user.createMany({ data: [ {username: "user1", age: 21}, {username: "user2", age: 23}, {username: "user3", age: 27} ], returning: ['id'] // 传入true可返回所有字段 }) // 提取所有插入的自增ID const insertedIds = batchInsertResult.map(item => item.id)
- 若版本不支持
returning语法,可通过事务实现:在事务中先查询当前表的最大自增ID值,再执行批量插入,结合返回的受影响行数,即可推算出本次插入生成的所有自增ID。该方案要求表自增步长为1,且事务隔离级别足够避免并发写入干扰,适合内部低并发场景使用。
createMany默认仅返回受影响行数的设计原因
- 跨库兼容性考虑:Prisma作为支持多数据库的ORM,早期版本适配的数据库(包括低版本MySQL、SQLite等)没有统一的批量插入返回多行记录的标准语法,如果强行要求返回插入的完整记录,会导致不同数据库下API行为不一致,因此选择所有数据库都能稳定支持的「返回受影响行数」作为默认实现,保证API行为跨库统一。
- 性能优先的定位:
createMany的核心设计目标是满足大数据量批量写入的性能需求,返回全量插入记录会额外增加数据库与应用间的传输开销,对于不需要获取ID的纯写入场景,仅返回count可以减少不必要的IO消耗,最大化批量写入效率。 - 场景区分:单条插入的
create方法定位是精准写入,通常后续业务逻辑会需要用到新生成的记录字段,因此默认返回完整对象;批量写入的createMany更多用于数据初始化、批量导入等不需要逐行处理返回值的场景,返回受影响行数更符合多数场景的使用预期。
内容的提问来源于stack exchange,提问作者Dzak
相关产品推荐
相关产品推荐

