6月2日 01:25

NestJS 怎么连数据库?TypeORM 和 Prisma 集成实战

NestJS 集成数据库的主流方案有两个:TypeORM(官方推荐,装饰器风格)和 Prisma(类型安全更好,迁移体验好)。选哪个看团队偏好——TypeORM 和 NestJS 风格统一,Prisma 的类型推导更强。

TypeORM 集成

bash
npm install @nestjs/typeorm typeorm pg

配置连接

typescript
// app.module.ts import { TypeOrmModule } from '@nestjs/typeorm'; @Module({ imports: [ TypeOrmModule.forRoot({ type: 'postgres', host: process.env.DB_HOST, port: 5432, username: process.env.DB_USER, password: process.env.DB_PASS, database: process.env.DB_NAME, autoLoadEntities: true, synchronize: false, // 生产环境必须 false }), ], }) export class AppModule {}

autoLoadEntities 自动加载注册了 TypeOrmModule.forFeature() 的实体,不用手动列。synchronize: false 防止生产环境自动改表结构(丢数据风险)。

定义实体

typescript
// users/user.entity.ts @Entity() export class User { @PrimaryGeneratedColumn('uuid') id: string; @Column({ unique: true }) email: string; @Column() password: string; @CreateDateColumn() createdAt: Date; }

在模块中注册

typescript
// users/users.module.ts @Module({ imports: [TypeOrmModule.forFeature([User])], providers: [UsersService], controllers: [UsersController], }) export class UsersModule {}

使用 Repository

typescript
// users/users.service.ts @Injectable() export class UsersService { constructor( @InjectRepository(User) private userRepo: Repository<User>, ) {} async findByEmail(email: string) { return this.userRepo.findOne({ where: { email } }); } async create(data: Partial<User>) { const user = this.userRepo.create(data); return this.userRepo.save(user); } }

Prisma 集成

bash
npm install prisma @prisma/client npx prisma init

定义 Schema

prisma
// prisma/schema.prisma model User { id String @id @default(uuid()) email String @unique password String createdAt DateTime @default(now()) posts Post[] } model Post { id String @id @default(uuid()) title String content String? authorId String author User @relation(fields: [authorId], references: [id]) createdAt DateTime @default(now()) }

生成迁移并应用

bash
npx prisma migrate dev --name init

在 NestJS 中使用

typescript
// prisma/prisma.service.ts @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit { async onModuleInit() { await this.$connect(); } } // users/users.service.ts @Injectable() export class UsersService { constructor(private prisma: PrismaService) {} async findByEmail(email: string) { return this.prisma.user.findUnique({ where: { email } }); } async create(data: { email: string; password: string }) { return this.prisma.user.create({ data }); } }

TypeORM vs Prisma 怎么选

维度TypeORMPrisma
查询方式装饰器 + Repository链式 API(自动补全强)
类型安全需要手动标注自动推导,几乎不需要类型标注
迁移工具内置但体验一般最好,migrate dev 自动生成 SQL
关联查询容易写出 N+1include 语法清晰
社区NestJS 官方推荐增长快,2024-2025 很多人从 TypeORM 迁过来

新项目推荐 Prisma——类型安全和迁移体验的优势在项目做大后会越来越明显。已有 TypeORM 的项目不必迁移,两者都能正常工作。

数据库迁移

生产环境绝对不能依赖 synchronize: true(自动同步 schema 到数据库),这会静默删列、改类型,导致数据丢失。

TypeORM 迁移

bash
npx typeorm migration:generate -n AddUserTable npx typeorm migration:run

Prisma 迁移

bash
npx prisma migrate dev --name add_user_table # 开发 npx prisma migrate deploy # 生产

migrate dev 生成迁移文件并应用,migrate deploy 只应用已有文件,适合 CI/CD。

标签:NestJS