NestJS 数据库文档入口
NestJS 官方文档中数据库相关内容分布在两处:
- Techniques > Database — 通用数据库集成指南
- Recipes(秘籍) — 各 ORM 的专项集成文档,包括 MikroORM、TypeORM、Mongoose、Sequelize、Prisma
中文文档的"秘籍"部分翻译尚不完整,如需参与翻译可访问官方 GitHub 贡献。
安装与初始化
安装 Prisma
pnpm add prisma @prisma/client
bash
prisma 是 CLI 工具(开发依赖),@prisma/client 是运行时客户端(生产依赖)。
确认版本:
npx prisma --version
# 当前版本参考:Prisma 6.x(2025/2026)
bash
初始化 Prisma 项目
npx prisma init
bash
该命令会生成两个文件:
| 文件 | 作用 |
|---|---|
prisma/schema.prisma | 数据模型定义文件 |
.env | 新增 DATABASE_URL 环境变量(如已存在则追加) |
VS Code 推荐安装 Prisma 扩展,提供
.prisma文件的语法高亮和自动补全。
VS Code 插件
在扩展市场搜索 "Prisma" 并安装。安装后 .prisma 文件会获得语法高亮、格式化和自动补全支持。
数据库连接配置
连接字符串格式
protocol://user:password@host:port/database?connection_arguments
text
各数据库的连接字符串示例:
| 数据库 | 连接字符串 |
|---|---|
| PostgreSQL | postgresql://root:example@localhost:5432/testdb?schema=public |
| MySQL | mysql://root:example@localhost:3306/testdb |
| SQLite | file:./dev.db |
| SQL Server | sqlserver://localhost:1433;database=testdb;user=SA;password=xxx;trustServerCertificate=true |
| MongoDB | mongodb://root:example@localhost:27017/testdb |
连接字符串支持 connection_arguments 参数,可以定制连接池大小、超时时间等。
环境变量配置
# .env
DATABASE_URL="mysql://root:example@localhost:3306/testdb"
bash
Prisma Schema 通过 env("DATABASE_URL") 读取连接字符串:
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
prisma
Docker 快速启动 MySQL
# docker-compose-mysql.yml
services:
mysql:
image: mysql:8.0
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: example
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
yaml
启动:
docker compose -f docker-compose-mysql.yml up -d
bash
使用 Adminer(端口 8080)可视化管理数据库:
adminer:
image: adminer
ports:
- "8080:8080"
yaml
Schema 定义
基础模型
// prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
username String
password String
}
prisma
| 属性 | 说明 |
|---|---|
@id | 标记为主键 |
@default(autoincrement()) | 自增策略 |
String?(加问号) | 可选字段(允许 null) |
@unique | 唯一约束 |
表名映射
Prisma 默认会将模型名作为表名。使用 @@map 可以自定义表名:
model User {
id Int @id @default(autoincrement()) @map("user_id")
username String
password String
@@map("user")
}
prisma
@map("user_id") 将 id 字段映射到数据库中的 user_id 列,@@map("user") 将模型映射到 user 表。
唯一索引
model User {
id Int @id @default(autoincrement())
username String @unique
password String
}
prisma
@unique 会在数据库层面创建唯一索引,防止重复数据。
数据库同步
db push(开发阶段推荐)
npx prisma db push
bash
db push 直接将 Schema 变更推送到数据库,不生成迁移文件。适合开发阶段快速迭代。
每次修改 Schema 后执行此命令即可同步到数据库。
migrate dev(生产推荐)
npx prisma migrate dev --name init
bash
migrate dev 会:
- 在
prisma/migrations/目录下生成 SQL 迁移文件 - 执行迁移到数据库
- 自动运行
prisma generate
迁移文件可以纳入版本控制,适合团队协作和生产环境。
生成 Client 类型
npx prisma generate
bash
根据 Schema 定义生成 TypeScript 类型定义,使得 prisma.user.findMany() 等操作获得完整的类型提示。
NestJS 集成
创建模块和服务
nest g module database/prisma --no-spec
nest g service database/prisma --no-spec
bash
PrismaService 封装
// database/prisma/prisma.service.ts
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
}
typescript
模块注册与导出
// database/prisma/prisma.module.ts
import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}
typescript
关键点:
@Global()— 声明为全局模块,其他模块无需重复 importexports: [PrismaService]— 必须导出,否则跨模块注入会报错
在 AppModule 中注册
// app.module.ts
import { Module } from '@nestjs/common';
import { PrismaModule } from './database/prisma/prisma.module';
@Module({
imports: [PrismaModule],
})
export class AppModule {}
typescript
在 Controller 中使用
// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { PrismaService } from './database/prisma/prisma.service';
@Controller()
export class AppController {
constructor(private readonly prisma: PrismaService) {}
@Get()
async findAll(): Promise<any> {
return this.prisma.user.findMany();
}
}
typescript
注入 PrismaService 后,直接通过 this.prisma.user 访问模型操作——user 对应 Schema 中的 model User。
常见错误排查
Provider 未导出
Error: PrismaService is a provider, are you sure you've exported it?
text
原因:跨模块使用 Service 时,模块必须将 Service 添加到 exports 数组中。
解决:在 PrismaModule 中添加 exports: [PrismaService],或使用 @Global() 装饰器。
数据库不存在
Error: P1003: Database testdb does not exist
text
解决:在 MySQL 中手动创建数据库:
CREATE DATABASE testdb;
sql
或通过 Adminer(localhost:8080)可视化创建。
Provider 类型不匹配
确保 Schema 中的 provider 与实际数据库一致。例如连接 MySQL 但 Schema 写的是 postgresql,需要改为:
datasource db {
provider = "mysql" // 不是 "postgresql"
url = env("DATABASE_URL")
}
prisma
synchronize 的危险性
TypeORM 提供 synchronize: true 选项,启动时自动同步实体定义到数据库。Prisma 没有等价选项(只有显式的 db push 和 migrate),这反而是个安全设计——避免因误操作导致生产数据丢失。
synchronize: true在实体变更时会直接修改数据库结构,如果删除了某个字段,该列的数据会被直接清除。生产环境禁止开启。
建议在环境配置中通过开关控制:
// main.ts 或配置模块中
const dbSync = configService.get<boolean>('DB_SYNC', false);
// 仅在 TypeORM 等方案中传递此值,Prisma 不需要
typescript
完整工作流总结
1. pnpm add prisma @prisma/client → 安装依赖
2. npx prisma init → 初始化 Schema
3. 修改 .env 中的 DATABASE_URL → 配置数据库连接
4. 定义 prisma/schema.prisma 中的 model → 设计数据模型
5. npx prisma db push → 同步 Schema 到数据库
6. npx prisma generate → 生成 TypeScript 类型
7. 封装 PrismaService + PrismaModule → NestJS 集成
8. 在 Controller 中注入使用 → 业务开发
text
集成完成后,后续章节将继续集成 TypeORM 和 Mongoose,对比三种方案的差异后,再进行统一的优化设计。
↑