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
这条命令会:
- 根据 schema 生成 SQL 迁移文件
- 执行迁移,在数据库里建表
- 生成 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 的 include 和 select 非常直观:
// 查用户及其文章
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 的对比
| 特性 | Sequelize | TypeORM | Prisma |
|---|---|---|---|
| TypeScript 支持 | 一般 | 好 | 极好 |
| 查询 API | 链式 | Repository / QueryBuilder | 生成 Client |
| 类型安全 | 弱 | 中等 | 强 |
| 迁移 | 有 | 有 | 优秀 |
| 性能 | 中等 | 中等 | 好 |
| 学习曲线 | 平缓 | 中等 | 中等 |