NestJS和Prisma:一个强大的组合

在 NestJS 中集成 Prisma 可以通过以下步骤实现。Prisma 是一个现代的 ORM 工具,能够简化数据库操作,而 NestJS 的模块化设计和依赖注入机制可以很好地与 Prisma 结合。以下是详细的实现步骤:


1. 安装依赖

首先,确保你的项目已经安装了 NestJS 和 Prisma 的相关依赖:

BASH

1npm install @nestjs/common @nestjs/core @nestjs/platform-express reflect-metadata 2npm install prisma @prisma/client 3npm install --save-dev @prisma/cli


2. 初始化 Prisma

在项目根目录下初始化 Prisma:

BASH

1npx prisma init

这会生成以下文件:

  • prisma/schema.prisma:定义数据模型和数据库连接配置。

  • .env:存储环境变量(如数据库连接字符串)。


3. 配置 Prisma Schema

prisma/schema.prisma 中定义你的数据模型和数据库连接。例如:

PRISMA

1// prisma/schema.prisma 2datasource db { 3 provider = "postgresql" 4 url = env("DATABASE_URL") 5} 6 7generator client { 8 provider = "prisma-client-js" 9} 10 11model User { 12 id Int @id @default(autoincrement()) 13 email String @unique 14 name String? 15 posts Post[] 16} 17 18model Post { 19 id Int @id @default(autoincrement()) 20 title String 21 content String? 22 author User? @relation(fields: [authorId], references: [id]) 23 authorId Int? 24}

注意:确保 DATABASE_URL.env 文件中定义:

ENV

1DATABASE_URL="postgresql://user:password@localhost:5432/dbname"


4. 生成 Prisma 客户端

运行以下命令生成 Prisma 客户端代码:

BASH

1npx prisma generate


5. 创建 NestJS 模块

在 NestJS 中创建一个全局模块来管理 Prisma 客户端,确保其在应用中唯一且可注入。

5.1 创建 Prisma 模块

src/prisma 目录下创建 prisma.module.ts

TYPESCRIPT

1import { Module } from '@nestjs/common'; 2import { PrismaClient } from '@prisma/client'; 3 4@Module({ 5 providers: [ 6 { 7 provide: 'PRISMA_SERVICE', 8 useFactory: async () => { 9 const prisma = new PrismaClient(); 10 return prisma; 11 }, 12 }, 13 ], 14 exports: ['PRISMA_SERVICE'], 15}) 16export class PrismaModule {}

5.2 标记为全局模块

app.module.ts 中导入并标记为全局模块:

TYPESCRIPT

1import { Module } from '@nestjs/common'; 2import { PrismaModule } from './prisma/prisma.module'; 3 4@Module({ 5 imports: [PrismaModule.forRoot()], // 如果需要配置,可以添加配置方法 6}) 7export class AppModule {}


6. 在服务中使用 Prisma

在需要操作数据库的服务中注入 Prisma 客户端。

6.1 创建服务

例如,创建 user.service.ts

TYPESCRIPT

1import { Injectable } from '@nestjs/common'; 2import { PrismaClient } from '@prisma/client'; 3 4@Injectable() 5export class UserService { 6 constructor(private readonly prisma: PrismaClient) {} 7 8 async findAll(): Promise<User[]> { 9 return this.prisma.user.findMany(); 10 } 11 12 async createUser(email: string, name: string): Promise<User> { 13 return this.prisma.user.create({ 14 data: { email, name }, 15 }); 16 } 17}

6.2 在控制器中使用服务

在控制器中注入服务并调用方法:

TYPESCRIPT

1import { Controller, Get, Post, Body } from '@nestjs/common'; 2import { UserService } from './user.service'; 3 4@Controller('users') 5export class UserController { 6 constructor(private readonly userService: UserService) {} 7 8 @Get() 9 async findAll(): Promise<User[]> { 10 return this.userService.findAll(); 11 } 12 13 @Post() 14 async create(@Body() createUserDto: CreateUserDto): Promise<User> { 15 return this.userService.createUser(createUserDto.email, createUserDto.name); 16 } 17}


7. 数据库迁移

使用 Prisma 的迁移功能来管理数据库结构:

BASH

1# 初始化迁移 2npx prisma migrate dev --name init 3 4# 应用迁移 5npx prisma migrate deploy


8. 环境变量配置

确保 NestJS 能够加载 .env 文件。可以在 main.ts 中添加:

TYPESCRIPT

1import * as dotenv from 'dotenv'; 2 3dotenv.config();


9. 完整代码结构示例

src/
├── app.module.ts
├── prisma/
│ ├── prisma.module.ts
├── user/
│ ├── user.controller.ts
│ ├── user.service.ts
│ └── user.dto.ts
├── main.ts
prisma/
├── schema.prisma
.env


10. 常见问题

10.1 模块未找到

确保 PrismaModule 已正确导入并标记为全局模块。

10.2 连接错误

检查 .env 中的 DATABASE_URL 是否正确,以及数据库是否运行。

10.3 Prisma 客户端未生成

运行 npx prisma generate 重新生成客户端代码。


总结

通过以上步骤,你可以在 NestJS 中无缝集成 Prisma。关键点包括:

  1. 依赖注入:将 Prisma 客户端作为服务注入。

  2. 模块化管理:使用 NestJS 模块确保单例和全局可用性。

  3. 数据库迁移:通过 Prisma 的迁移工具保持数据库结构同步。

Prisma 的查询 API 非常直观,例如:

TYPESCRIPT

1// 查询所有用户 2this.prisma.user.findMany(); 3 4// 创建用户 5this.prisma.user.create({ data: { email: 'test@example.com', name: 'Test' } });

更多高级用法(如事务、关系查询)可参考 Prisma 官方文档


NestJS和Prisma:一个强大的组合
http://localhost:8090/archives/nestjshe-prisma-yi-ge-qiang-da-de-zu-he
作者
Administrator
发布于
2025年05月07日
更新于
2025年05月19日
许可协议