Nest.js后端使用TypeORM获取某表最后新增行并生成id+1
解决方案
针对你用Nest.js + TypeORM获取表中最后新增行的非自增ID并生成ID+1的需求,这里提供两种可行方案:
方案一:通过Repository查询排序后的第一条数据
利用TypeORM的findOne方法,按数据的创建时间(或更新时间)倒序排序,直接获取最新插入的行,再提取ID进行计算。假设你的实体类名为TargetEntity,非自增ID字段为customId,创建时间字段为createdAt:
// 在对应的Service中注入Repository constructor( @InjectRepository(TargetEntity) private readonly targetRepo: Repository<TargetEntity>, ) {} async getNextCustomId(): Promise<number> { // 按创建时间倒序取最新的一条数据 const latestRecord = await this.targetRepo.findOne({ order: { createdAt: 'DESC', // 若没有创建时间,也可按customId倒序(需保证ID是递增插入的) }, }); // 如果表为空,返回初始值(比如1),否则返回customId + 1 return latestRecord ? latestRecord.customId + 1 : 1; }
方案二:使用QueryBuilder实现高效查询
如果数据量较大,QueryBuilder的写法更灵活,还可以配合聚合函数直接获取最大ID,无需返回整条数据:
async getNextCustomId(): Promise<number> { const result = await this.targetRepo .createQueryBuilder('entity') .select('MAX(entity.customId)', 'maxId') .getRawOne(); // 处理空表情况 return result.maxId ? result.maxId + 1 : 1; }
注意事项
- 并发冲突问题:如果多个请求同时调用这个方法,可能会出现重复生成ID的情况。建议在生成ID并插入新数据的过程中使用事务,或者在查询时加锁(比如MySQL的
SELECT ... FOR UPDATE),避免并发写入冲突:async getNextCustomIdWithLock(): Promise<number> { const result = await this.targetRepo .createQueryBuilder('entity') .select('MAX(entity.customId)', 'maxId') .setLock('pessimistic_write') // 悲观锁,防止其他事务修改数据 .getRawOne(); return result.maxId ? result.maxId + 1 : 1; } - 若你的非自增ID不是数值类型,需要根据实际类型调整计算逻辑(比如字符串拼接递增序号)。
内容的提问来源于stack exchange,提问作者user23873606
相关产品推荐
相关产品推荐

