写在前面

在 NestJS 项目中选择合适的数据库工具对开发效率和代码可维护性至关重要。Prisma 作为新一代类型安全的数据库客户端,凭借其声明式数据模型自动生成的查询 API直观的迁移系统,正逐渐成为许多开发者的首选。

本文将演示如何在 NestJS 中集成 Prisma,从初始化配置、定义数据模型,到执行数据库迁移,并基于实际字段说明表结构。同时,也会简要对比传统 ORM(如 TypeORM)的实现方式,帮助你更清晰地理解两者在代码组织与开发体验上的差异。

所有步骤均以可运行为目标,适用于希望快速上手 Prisma 的 NestJS 开发者。


创建 Prisma 服务

首先,通过以下命令初始化 Prisma

npx prisma init 

该命令会自动完成两件事:

1.在项目根目录生成 prisma/ 文件夹(包含 schema.prisma);

2.创建 .env 文件,并预置 DATABASE_URL 环境变量。

同时,你需要手动安装 prisma 作为开发依赖(如果尚未安装):

接下来,修改 .env 文件中的数据库连接地址。
这里以 PostgreSQL 为例,你可以根据自己的数据库类型和配置进行调整:

DATABASE_URL="postgresql://postgres:your_password@localhost:5432/xue?schema=public"

配置完成后,终端通常会显示初始化成功的提示信息,表示 Prisma 已正确设置。

初始化完成后,你会看到 prisma/schema.prisma 文件的默认内容大致如下:

接下来,我们在 schema.prisma 中定义数据模型。

这里以两个常见的表为例:User 和 Post

model User {
  id          Int        @id @default(autoincrement())
  name        String     @unique @db.VarChar(255)
  password    String     @db.VarChar(255)
  createdAt   DateTime?  @default(now()) @map("created_at") @db.Timestamptz(6)
  updatedAt   DateTime?  @default(now()) @map("updated_at") @db.Timestamptz(6)
  posts       Post[]
  comments    Comment[]
  likes       UserLikePost[]
  avatars     Avatar[]
  files       File[]
  @@map("users")
}

model Post {
  id          Int        @id @default(autoincrement())
  title       String     @db.VarChar(255)
  content     String?    @db.Text
  userId      Int?
  user        User?      @relation(fields:[userId], references: [id], onDelete: SetNull)
  comments    Comment[]
  tags        PostTag[]
  likes       UserLikePost[]
  files       File[]
  @@index([userId])
  @@map("posts")
}

这两个模型将分别映射到数据库中的 users 和 posts 表,并通过外键建立关联。

User 表(数据库表名:users)包含字段

id:主键,自增整数,唯一标识用户。

name:用户名,字符串类型,唯一(不能重复),最大长度 255。

password:密码(通常存储哈希值),字符串类型,最大长度 255。

created_at:用户创建时间,默认为当前时间戳,时区感知(timestamptz)。

updated_at:最后更新时间,默认为当前时间戳,可用于记录修改时间。

Post 表(数据库表名:posts)包含字段

id:主键,自增整数,唯一标识文章。

title:文章标题,字符串类型,最大长度 255。

content:文章内容,文本类型,可为空

user_id:外键,关联 users.id,表示该文章的作者;允许为空(因为 onDelete: SetNull,作者被删时设为 NULL)。

我们定义好数据模型,接着来运行下数据库的迁移命令:

npx prisma migrate dev --name init

其中 --name init 是本次迁移的名称,你可以根据实际变更内容自定义(例如 add_user_and_post),便于后续维护。

迁移成功后,数据库中就会自动创建 users 和 posts 两张表,结构与你在 Prisma Schema 中定义的一致。

没有prisma时

讲了那么多,我们来看看没有prisma时会怎么做,对比一下

1. 定义实体(Entity)

// user.entity.ts
@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ unique: true })
  email: string;

  @Column()
  password: string;
}

2. 在 Service 中操作

// auth.service.ts
async register(email: string, password: string) {
  const existing = await this.userRepository.findOne({ where: { email } });
  if (existing) throw new ConflictException('Email exists');

  const user = this.userRepository.create({
    email,
    password: hash(password),
  });
  await this.userRepository.save(user);
  
  delete user.password; // 或用 class-transformer 排除
  return user;
}

二者不同之处

用 Prisma,你只需要写一个 schema.prisma 文件,定义好模型,剩下的增删改查、类型提示、数据库迁移,它都给你生成好。代码少,类型安全,出错早。

不用 Prisma(比如用 TypeORM),你得手动写 Entity 类,加一堆装饰器;查数据要调 Repository 或 QueryBuilder,关联关系靠注解配;改个字段,既要改 Entity,又要写 migration 脚本,还容易漏。

说白了:

一个重配置,一个重编码。选哪个,看你想和谁打交道——和文件打交道,还是和模板代码打交道。

总结

Prisma确实让数据库操作变得更简单、更可预测。

在 NestJS 中集成它,只需几步:定义模型、跑迁移、调用生成的客户端。

没有冗余装饰器,没有手动写 Repository,也没有模糊的类型推断。

如果你受够了在 ORM 里反复写样板代码,只想专注业务逻辑,Prisma 值得一试。

反之,若项目已重度依赖 TypeORM,或需要极细粒度的 SQL 控制,那传统方式也无妨。

工具没有高下,只有合不合适。但至少现在,你知道多了一种更清爽的选择。

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com