前置要求

  • 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 prisma

src/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 users

src/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(不生成迁移文件)
Last modification:April 14, 2026
如果觉得我的文章对你有用,请随意赞赏。