前置要求
- Node.js >= 18
- PostgreSQL 已安装并运行
- pnpm 已安装(
npm i -g pnpm)
第一步:创建 NestJS 项目
pnpm i -g @nestjs/cli
nest new my-app
cd my-app选择 pnpm 作为包管理器。
第二步:安装所有依赖
一次性安装完所有需要的包,避免后续遗漏:
# Prisma CLI
pnpm add -D prisma
# Prisma Client + PostgreSQL adapter(Prisma 7 运行时必须)
pnpm add @prisma/client @prisma/adapter-pg pg dotenv
# pg 类型
pnpm add -D @types/pg第三步:初始化 Prisma
npx prisma init执行后生成:
prisma/
schema.prisma
prisma.config.ts ← Prisma 7 新增
.env第四步:配置数据库连接
.env:
DATABASE_URL="postgresql://用户名:密码@localhost:5432/数据库名?schema=public"
# 例如:
DATABASE_URL="postgresql://postgres:123456@localhost:5432/myapp?schema=public"prisma.config.ts(替换自动生成的内容):
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});第五步:定义数据模型
prisma/schema.prisma(注意:保留 datasource 块但不写 url):
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
createdAt DateTime @default(now())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
createdAt DateTime @default(now())
}⚠️datasource块必须保留(Prisma CLI 需要它识别数据库类型),但url不写在这里,改由prisma.config.ts提供。
第六步:执行数据库迁移
npx prisma migrate dev --name init成功后会在 prisma/migrations/ 下生成迁移文件,并在数据库中创建对应的表。
第七步:创建 Prisma 模块
nest generate module prisma
nest generate service prismasrc/prisma/prisma.service.ts:
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
import { PrismaPg } from '@prisma/adapter-pg';
@Injectable()
export class PrismaService extends PrismaClient
implements OnModuleInit, OnModuleDestroy {
constructor() {
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
super({ adapter });
}
async onModuleInit() {
await this.$connect();
}
async onModuleDestroy() {
await this.$disconnect();
}
}src/prisma/prisma.module.ts:
import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}第八步:创建 Users 业务模块
nest generate module users
nest generate controller users
nest generate service userssrc/users/users.service.ts:
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { User, Prisma } from '@prisma/client';
@Injectable()
export class UsersService {
constructor(private prisma: PrismaService) {}
async findAll(): Promise<User[]> {
return this.prisma.user.findMany();
}
async findOne(id: number): Promise<User | null> {
return this.prisma.user.findUnique({ where: { id } });
}
async create(data: Prisma.UserCreateInput): Promise<User> {
return this.prisma.user.create({ data });
}
async update(id: number, data: Prisma.UserUpdateInput): Promise<User> {
return this.prisma.user.update({ where: { id }, data });
}
async remove(id: number): Promise<User> {
return this.prisma.user.delete({ where: { id } });
}
}src/users/users.controller.ts:
import { Controller, Get, Post, Put, Delete, Param, Body, ParseIntPipe } from '@nestjs/common';
import { UsersService } from './users.service';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll() {
return this.usersService.findAll();
}
@Get(':id')
findOne(@Param('id', ParseIntPipe) id: number) {
return this.usersService.findOne(id);
}
@Post()
create(@Body() body: { email: string; name?: string }) {
return this.usersService.create(body);
}
@Put(':id')
update(
@Param('id', ParseIntPipe) id: number,
@Body() body: { name?: string },
) {
return this.usersService.update(id, body);
}
@Delete(':id')
remove(@Param('id', ParseIntPipe) id: number) {
return this.usersService.remove(id);
}
}src/users/users.module.ts(nest generate 自动生成,无需修改):
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
@Module({
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}第九步:注册模块 & 加载环境变量
src/app.module.ts:
import { Module } from '@nestjs/common';
import { PrismaModule } from './prisma/prisma.module';
import { UsersModule } from './users/users.module';
@Module({
imports: [PrismaModule, UsersModule],
})
export class AppModule {}src/main.ts(顶部加载 dotenv,必须在第一行):
import 'dotenv/config';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();第十步:启动项目
pnpm run start:dev最终目录结构
├── prisma/
│ ├── migrations/
│ └── schema.prisma
├── src/
│ ├── prisma/
│ │ ├── prisma.module.ts
│ │ └── prisma.service.ts
│ ├── users/
│ │ ├── users.module.ts
│ │ ├── users.controller.ts
│ │ └── users.service.ts
│ ├── app.module.ts
│ └── main.ts
├── prisma.config.ts
├── .env
└── package.json测试接口
# 创建用户
curl -X POST http://localhost:3000/users \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","name":"张三"}'
# 查询所有用户
curl http://localhost:3000/users
# 查询单个用户
curl http://localhost:3000/users/1
# 更新用户
curl -X PUT http://localhost:3000/users/1 \
-H "Content-Type: application/json" \
-d '{"name":"李四"}'
# 删除用户
curl -X DELETE http://localhost:3000/users/1常用 Prisma 命令
| 命令 | 说明 |
|---|---|
npx prisma migrate dev | 开发环境迁移 |
npx prisma migrate deploy | 生产环境迁移 |
npx prisma generate | 重新生成 Client 类型 |
npx prisma studio | 可视化数据库管理界面 |
npx prisma db push | 快速同步 schema(不生成迁移文件) |