首页 / Node.js 教程 / ORM 与 Prisma

Node.js 教程

ORM 与 Prisma

本教程共 76 篇 · 第 53 篇 · 更新于 2026-07-25 · 约 3 分钟阅读

Node.jsPrismaORM类型安全迁移

53. ORM 与 Prisma

本节目标:用 Prisma 定义模型、迁移和类型安全的数据库访问。

ORM(Object-Relational Mapping)把数据库表映射成代码里的对象,让你用操作对象的方式操作数据库,不用手写 SQL。Sequelize、TypeORM、Prisma 是 Node.js 生态里最常见的三个。本章重点讲 Prisma——目前活跃度最高、TypeScript 支持最好的一个。

为什么选 Prisma

Sequelize 老牌但 TypeScript 支持一般;TypeORM 装饰器语法优雅,但 issue 多、迭代慢。Prisma 的特点是:

  • Schema 声明式定义,自带类型推导
  • 生成的 Client 全是类型安全的,IDE 自动补体验极好
  • 迁移系统成熟,团队协作不容易乱
  • 查询引擎用 Rust 写的,性能不错

初始化项目

npm install prisma @prisma/client
npx prisma init

执行后生成:

prisma/
  schema.prisma    # 数据模型定义
.env               # 数据库连接串

.env 里配连接串:

DATABASE_URL="mysql://root:123456@localhost:3306/myapp"

定义 Schema

prisma/schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String
  posts     Post[]
  createdAt DateTime @default(now()) @map("created_at")

  @@map("users")
}

model Post {
  id       Int     @id @default(autoincrement())
  title    String
  content  String? // ? 表示可空
  published Boolean @default(false)
  author   User    @relation(fields: [authorId], references: [id])
  authorId Int     @map("author_id")

  @@map("posts")
}
  • @id 主键,@default(autoincrement()) 自增
  • @unique 唯一约束
  • @relation 定义外键关系
  • @@map 把模型名映射到不同的表名

迁移与生成 Client

npx prisma migrate dev --name init

这条命令会:

  1. 根据 schema 生成 SQL 迁移文件
  2. 执行迁移,在数据库里建表
  3. 生成 Prisma Client(node_modules/.prisma/client

之后改 schema 就再跑一次 migrate dev

用 Prisma Client 查询

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

// 创建用户
const user = await prisma.user.create({
  data: { email: 'alice@example.com', name: 'Alice' }
});

// 关联创建:用户 + 文章
const userWithPosts = await prisma.user.create({
  data: {
    email: 'bob@example.com',
    name: 'Bob',
    posts: {
      create: [{ title: '第一篇' }, { title: '第二篇' }]
    }
  },
  include: { posts: true }
});

// 查询单条
const found = await prisma.user.findUnique({
  where: { email: 'alice@example.com' }
});

// 列表 + 条件 + 排序 + 分页
const list = await prisma.user.findMany({
  where: { name: { contains: 'A' } },
  orderBy: { createdAt: 'desc' },
  skip: 0,
  take: 10
});

// 更新
await prisma.user.update({
  where: { id: 1 },
  data: { name: 'Alice Wang' }
});

// 删除
await prisma.user.delete({ where: { id: 1 } });

关联查询

Prisma 的 includeselect 非常直观:

// 查用户及其文章
const user = await prisma.user.findUnique({
  where: { id: 1 },
  include: { posts: { where: { published: true } } }
});

// 只查特定字段
const slim = await prisma.user.findMany({
  select: { id: true, email: true }
});

事务

Prisma 支持两种事务方式:

// 方式一:串行事务(interactive)
await prisma.$transaction([
  prisma.user.create({ data: { ... } }),
  prisma.post.create({ data: { ... } })
]);

// 方式二:交互式事务
await prisma.$transaction(async (tx) => {
  const user = await tx.user.create({ data: { ... } });
  await tx.post.create({ data: { authorId: user.id, ... } });
});

第二种可以在事务里根据前面操作的结果决定后面的逻辑,更灵活。

和其他 ORM 的对比

特性SequelizeTypeORMPrisma
TypeScript 支持一般极好
查询 API链式Repository / QueryBuilder生成 Client
类型安全中等
迁移优秀
性能中等中等
学习曲线平缓中等中等