在 NestJS 项目中集成 Prisma ORM,实现数据库操作


一、初始化 Prisma

首先在项目根目录初始化 Prisma,这会生成必要的配置文件:

npx prisma init

执行后会生成以下文件:

  • prisma/schema.prisma - 数据模型定义文件

  • prisma/prisma.config.ts - Prisma 配置文件

  • .env - 环境变量文件


二、定义数据模型

2.1 编写 schema.prisma

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

// Get a free hosted Postgres database in seconds: `npx create-db`

generator client {
  provider     = "prisma-client" // 生成 Prisma 客户端代码
  output       = "../src/db/generated/prisma" // 生成的输出目录
  moduleFormat = "cjs" // 生成的模块格式,nestjs 默认打包 cjs 格式模块
}

datasource db {
  provider = "postgresql" // 数据库提供程序
}

model User {
  /// 用户唯一标识
  id        String    @id @default(cuid())
  /// 用户姓名
  name      String
  /// 用户邮箱
  email     String    @unique
  /// 用户密码
  password  String
  /// 创建时间
  createdAt DateTime  @default(now())
  /// 更新时间
  updatedAt DateTime?
  /// 软删除时间
  deletedAt DateTime?
}

model Payment {
  /// 支付记录唯一标识
  id        String    @id @default(cuid())
  /// 关联的用户标识
  userId    String
  /// 关联的支付金额
  amount    Int
  /// 关联的支付货币
  currency  String
  /// 创建时间
  createdAt DateTime  @default(now())
  /// 更新时间
  updatedAt DateTime?
}

2.2 主键生成策略

策略

说明

cuid()

生成 CUID 格式的唯一标识(推荐)

uuid()

生成 UUID 格式的唯一标识

autoincrement()

生成自增整数


三、配置 Prisma

3.1 编写 prisma.config.ts

// This file was generated by Prisma, and assumes you have installed the following:
// npm install --save-dev prisma dotenv
import 'dotenv/config';
import { defineConfig } from 'prisma/config';

// eslint-disable-next-line @typescript-eslint/no-unsafe-call
export default defineConfig({
  schema: 'prisma/schema.prisma', // 数据库模型文件路径
  // 生成数据库迁移配置
  migrations: {
    path: 'prisma/migrations', // 生成数据库迁移文件路径
  },
  datasource: {
    url: process.env['DATABASE_URL'], // 数据库连接字符串
  },
});

四、安装依赖

npm install prisma dotenv @prisma/client @prisma/adapter-pg pg

各包作用说明

包名

作用

必要性

prisma

Prisma CLI 命令行工具,提供迁移、生成等命令

必需

dotenv

加载 .env 环境变量文件

必需

@prisma/client

Prisma Client ORM 客户端,用于数据库操作

必需

@prisma/adapter-pg

Prisma 与 PostgreSQL 的适配器

视数据库类型而定

pg

node-postgres 数据库驱动程序

视数据库类型而定

@types/pg

node-postgres 的 TypeScript 类型定义

开发依赖

4.1 Prisma CLI

  • Prisma 的核心 CLI 工具

  • 提供 prisma initprisma migrateprisma generateprisma studio 等命令

  • 用于初始化项目、管理数据库迁移、生成代码

4.2 dotenv

  • 加载 .env 文件中的环境变量

  • Prisma 配置文件需要从环境变量读取 DATABASE_URL

  • 确保敏感配置不硬编码

4.3 @prisma/client

  • Prisma 的 ORM 客户端库

  • 根据 schema.prisma 生成类型安全的数据库操作方法

  • 提供查询、创建、更新、删除等 CRUD 操作

  • 支持自动类型推断,提供更好的开发体验

4.4 @prisma/adapter-pg

  • PostgreSQL 数据库适配器

  • 允许与 pg 库共享连接池

  • 支持事务嵌套等高级特性

4.5 数据库适配器选择

数据库

适配器包

PostgreSQL

@prisma/adapter-pg

MySQL

@prisma/adapter-mariadb

SQLite

@prisma/adapter-better-sqlite3

SQL Server

@prisma/adapter-mssql

MongoDB

无需额外适配器

4.6 安装命令总结

# 基础安装(必需)
npm install prisma dotenv @prisma/client

# 根据数据库类型安装适配器(可选但推荐)
npm install @prisma/adapter-pg  # PostgreSQL
npm install @prisma/adapter-mysql  # MySQL
npm install @prisma/adapter-sqlite  # SQLite

五、数据库迁移

5.1 生成迁移文件

npx prisma migrate dev --name init

参数说明

  • migrate dev - 应用迁移文件

  • --name init - 指定迁移名称

5.2 迁移原理

迁移文件会根据 schema.prisma 生成对应的 SQL 语句,用于创建数据库表。每次修改 schema.prisma 后,都需要重新生成迁移文件,记录每次的修改历史,便于部署阶段使用。


六、生成 Prisma Client

npx prisma generate

参数说明

  • generate - 生成 Prisma Client 代码

  • --output - 指定输出目录(可选)

生成的文件用途

生成的代码提供类型安全的数据库操作方法,自动声明了模型的字段类型,无需手动编写类型定义。每次修改 schema.prisma 后都需要重新生成。

.gitignore 配置

建议忽略自动生成的目录:

# Prisma generated files
src/db/generated/

七、创建 NestJS Prisma 服务

7.1 生成模块和服务

nest g s prisma
nest g mo prisma

7.2 编写 PrismaService

// src/db/prisma/prisma.service.ts
import { Injectable } from '@nestjs/common';

/** 导入 Prisma Client 库 */
import { PrismaClient } from '../generated/prisma/client';

/** 导入 Prisma PostgreSQL 数据库适配器 */
import { PrismaPg } from '@prisma/adapter-pg';

import 'dotenv/config';

@Injectable()
export class PrismaService extends PrismaClient {
  constructor() {
    const adapter = new PrismaPg({
      connectionString: process.env['DATABASE_URL'],
    });
    super({ adapter });
  }
}

八、注册 Prisma 服务

8.1 局部注册

在需要使用的模块中导入:

// src/user/user.module.ts
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { PrismaModule } from '../db/prisma/prisma.module';

@Module({
  controllers: [UserController],
  providers: [UserService],
  imports: [PrismaModule], // 导入 PrismaModule 模块
})
export class UserModule {}

使用示例

import { Injectable } from '@nestjs/common';
/** 导入 PrismaService 服务 */
import { PrismaService } from '../db/prisma/prisma.service';

@Injectable()
export class UserService {
  constructor(private prismaService: PrismaService) {}

  async findAll() {
    return await this.prismaService.user.findMany();
  }
}

输出示例

{
  "timestamp": "2026-05-06T06:41:13.124Z",
  "data": [
    {
      "id": "cmotouum70000s8isi5fk97mw",
      "name": "linzex",
      "email": "linzex@example.com",
      "password": "123456",
      "createdAt": "2026-05-06T06:40:55.423Z",
      "updatedAt": null,
      "deletedAt": null
    }
  ],
  "path": "/v1.0.0/user",
  "method": "GET",
  "message": "success"
}

8.2 全局注册

通过 @Global() 装饰器将模块标记为全局模块,其他模块可直接注入:

import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';

@Global() // 全局模块标记
@Module({
  providers: [PrismaService],
  exports: [PrismaService],
})
export class PrismaModule {}

全局注册优势

  • 无需在每个模块中重复导入

  • 简化模块配置

  • 适合基础服务(数据库、配置、日志等)