Prisma 详尽教程
Prisma 是一个现代化的数据库工具链,包含 Prisma Client(自动生成的类型安全查询构建器)、Prisma Migrate(迁移系统)和 Prisma Studio(数据库 GUI)。本教程将全面介绍 Prisma 的各个方面。
目录
- Prisma 核心概念
- 安装与设置
- 数据建模
- Prisma Client 使用
- 高级查询
- 关系处理
- Prisma Migrate
- Prisma Studio
- 与框架集成
- 最佳实践
Prisma 核心概念
1. Prisma Schema
定义数据模型的核心文件,位于 prisma/schema.prisma
,包含:
- 数据源 (数据库连接)
- 生成器 (客户端生成配置)
- 数据模型定义
2. Prisma Client
自动生成的类型安全数据库客户端,提供:
- CRUD 操作
- 类型安全查询
- 关系查询
3. Prisma Migrate
数据库迁移工具,特点:
- 基于声明的数据模型
- 生成迁移历史
- 保持开发与生产环境同步
安装与设置
1. 初始化项目
npm init -y
npm install prisma typescript ts-node @types/node --save-dev
npx tsc --init
npx prisma init
2. 配置数据库连接
编辑 prisma/schema.prisma
:
prisma
datasource db {
provider = "postgresql" // 或 mysql, sqlite, sqlserver, mongodb
url = env("DATABASE_URL")
}
在 .env
文件中设置连接字符串:
env
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
3. 安装 Prisma Client
npm install @prisma/client
数据建模
1. 基本模型定义
prisma
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
createdAt DateTime @default(now())
posts Post[]
}
2. 字段类型与修饰符
- 标量类型:
Int
,String
,Boolean
,DateTime
,Float
,Decimal
,Json
,Bytes
- 修饰符:
@id
- 主键@unique
- 唯一约束@default
- 默认值@updatedAt
- 自动更新时间戳
3. 枚举类型
prisma
enum Role {
USER
ADMIN
}
model User {
id Int @id @default(autoincrement())
role Role @default(USER)
}
Prisma Client 使用
1. 初始化客户端
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
// 查询操作将在这里进行
}
main()
.catch(e => {
throw e
})
.finally(async () => {
await prisma.$disconnect()
})
2. CRUD 操作
创建记录:
const user = await prisma.user.create({
data: {
name: 'Alice',
email: 'alice@prisma.io',
},
})
查询单个记录:
const user = await prisma.user.findUnique({
where: {
email: 'alice@prisma.io',
},
})
更新记录:
const updatedUser = await prisma.user.update({
where: {
email: 'alice@prisma.io',
},
data: {
name: 'Alicia',
},
})
删除记录:
const deletedUser = await prisma.user.delete({
where: {
email: 'alice@prisma.io',
},
})
高级查询
1. 过滤与分页
const users = await prisma.user.findMany({
where: {
name: {
contains: 'alice',
},
},
skip: 10, // 跳过前10条
take: 5, // 取5条
orderBy: {
createdAt: 'desc',
},
})
2. 聚合查询
const aggregations = await prisma.user.aggregate({
_count: {
_all: true,
},
_avg: {
age: true,
},
where: {
role: 'ADMIN',
},
})
3. 原生 SQL 查询
const result = await prisma.$queryRaw`
SELECT * FROM User WHERE email = ${email}
`
关系处理
1. 一对一关系
prisma
model Profile {
id Int @id @default(autoincrement())
bio String?
user User @relation(fields: [userId], references: [id])
userId Int @unique
}
model User {
id Int @id @default(autoincrement())
profile Profile?
}
2. 一对多关系
prisma
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id])
authorId Int
}
model User {
id Int @id @default(autoincrement())
posts Post[]
}
3. 多对多关系
prisma
model Post {
id Int @id @default(autoincrement())
categories Category[]
}
model Category {
id Int @id @default(autoincrement())
posts Post[]
}
4. 级联操作
prisma
model User {
id Int @id @default(autoincrement())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
authorId Int
}
Prisma Migrate
1. 创建迁移
npx prisma migrate dev --name init
2. 应用迁移到生产环境
npx prisma migrate deploy
3. 重置数据库
npx prisma migrate reset
4. 迁移历史
npx prisma migrate status
Prisma Studio
启动可视化数据库管理工具:
npx prisma studio
与框架集成
1. 与 Express 集成
import express from 'express'
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
const app = express()
app.get('/users', async (req, res) => {
const users = await prisma.user.findMany()
res.json(users)
})
app.listen(3000, () =>
console.log('Server running on port 3000'))
2. 与 Next.js 集成
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
export async function getServerSideProps() {
const users = await prisma.user.findMany()
return { props: { users } }
}
3. 全局 Prisma 客户端实例
为了避免多个 Prisma 客户端实例,可以创建共享实例:
import { PrismaClient } from '@prisma/client'
const globalForPrisma = global as unknown as { prisma: PrismaClient }
export const prisma = globalForPrisma.prisma || new PrismaClient()
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
最佳实践
- 环境分离:
- 为开发、测试和生产环境使用不同的数据库
- 使用
.env
文件管理连接字符串
- 错误处理:
try { await prisma.user.create({ data: { email: 'existing@email.com' } }) } catch (e) { if (e instanceof Prisma.PrismaClientKnownRequestError) { if (e.code === 'P2002') { console.log('唯一约束冲突') } } throw e }
- 性能优化:
- 使用
select
只查询需要的字段 - 合理使用事务
- 批量操作时使用
createMany
和updateMany
- 使用
- 日志记录:
const prisma = new PrismaClient({ log: ['query', 'info', 'warn', 'error'], })
- 连接池管理:
const prisma = new PrismaClient({ datasources: { db: { url: 'postgresql://user:password@localhost:5432/mydb?connection_limit=5', }, }, })
总结
Prisma 提供了现代化的数据库访问体验,通过本教程您已经学习了:
- 数据建模与迁移
- 基本的 CRUD 操作
- 高级查询技巧
- 关系处理
- 与各种框架的集成
- 生产环境最佳实践
Prisma 的类型安全特性和直观的 API 设计可以显著提高开发效率,同时减少数据库相关的错误。随着项目的增长,Prisma 的迁移系统和查询优化功能也能帮助维护数据库的健康状态。