NestJS初学者求教:如何无需循环向PostgreSQL批量插入数据?
批量插入PostgreSQL数据(NestJS + TypeORM)
循环单条插入会频繁建立数据库连接,大幅降低性能,下面提供三种无需循环的批量插入方案,适配不同场景:
方法1:使用Repository的save方法(最简单)
TypeORM的save方法原生支持传入实体数组,内部会自动处理批量插入逻辑:
import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Feature } from './feature.entity'; @Injectable() export class AppService { constructor(@InjectRepository(Feature) private readonly featureRepository: Repository<Feature>){} async addData(data: Feature[]){ // 直接传入实体数组即可完成批量插入 await this.featureRepository.save(data); return true; } }
注意:如果实体配置了自增ID,确保传入数据中没有重复ID,或让数据库自动生成ID(根据你的实体定义调整)
方法2:使用QueryBuilder(更灵活可控)
QueryBuilder允许你精确控制插入字段、条件等,适合需要自定义插入逻辑的场景:
import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Feature } from './feature.entity'; @Injectable() export class AppService { constructor(@InjectRepository(Feature) private readonly featureRepository: Repository<Feature>){} async addData(data: Feature[]){ await this.featureRepository.createQueryBuilder() .insert() .into(Feature) .values(data) .execute(); return true; } }
如果只需插入特定字段(比如跳过id字段),可以指定列名:
await this.featureRepository.createQueryBuilder() .insert() .into(Feature) .columns(['name', 'phone']) .values(data.map(item => ({ name: item.name, phone: item.phone }))) .execute();
方法3:原生SQL批量插入(兼容原有写法)
若偏好原生SQL,可以构建批量VALUES子句,一次执行插入:
import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Feature } from './feature.entity'; @Injectable() export class AppService { constructor(@InjectRepository(Feature) private readonly featureRepository: Repository<Feature>){} async addData(data: any[]){ if(data.length === 0) return true; // 构建批量占位符,格式如($1,$2,$3),($4,$5,$6)... const placeholders = data.map((_, index) => { const start = index * 3 + 1; return `($${start}, $${start+1}, $${start+2})`; }).join(','); // 整理所有参数到一个一维数组 const params = data.flatMap(item => [item.id, item.name, item.phone]); await this.featureRepository.manager.query( `INSERT INTO public.feature(id, name, phone) VALUES ${placeholders}`, params ); return true; } }
注意事项
- 数据量限制:PostgreSQL默认单条SQL的参数上限为65535,若数据量极大,建议分批次插入(比如每1000条一批)
- 字段匹配:确保传入的
data数组字段与实体/数据库表字段完全一致,避免插入失败
内容的提问来源于stack exchange,提问作者umer
相关产品推荐
相关产品推荐

