跳到主要内容

Prisma深入指南

什么是Prisma?

Prisma是一个现代的ORM(Object-Relational Mapping)工具,为Node.js和TypeScript应用程序提供数据库访问。它提供了类型安全的数据库查询API,自动生成的TypeScript类型,以及强大的迁移工具,使数据库操作更加安全、高效和愉悦。

安装与配置

安装Prisma CLI

npm install prisma --save-dev

初始化Prisma项目

npx prisma init

这将创建以下文件和目录:

  • prisma/schema.prisma:定义数据库模型和连接配置
  • .env:存储数据库连接URL

配置数据库连接

.env文件中配置数据库连接URL:

DATABASE_URL="postgresql://username:password@localhost:5432/mydatabase"

Prisma Schema

schema.prisma文件是Prisma的核心配置文件,用于定义数据库模型和连接配置。

基本结构

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

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

model User {
id Int @id @default(autoincrement())
name String?
email String @unique
password String
posts Post[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}

model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}

数据模型定义

字段类型

Prisma支持多种数据类型:

  • 标量类型:String, Boolean, Int, Float, DateTime, Json, Bytes
  • 复合类型:对象、数组
  • 特殊类型:枚举、关联字段

字段属性

  • @id:主键
  • @unique:唯一约束
  • @default(value):默认值
  • @updatedAt:自动更新时间戳
  • @relation:定义关系

数据库迁移

创建迁移

当修改了Prisma Schema后,需要创建迁移来应用这些更改到数据库:

npx prisma migrate dev --name init

这将:

  1. 生成SQL迁移文件
  2. 应用迁移到数据库
  3. 重新生成Prisma Client

查看迁移历史

npx prisma migrate status

重置数据库

npx prisma migrate reset

Prisma Client

Prisma Client是一个自动生成的类型安全数据库客户端,提供流畅的API用于数据库操作。

安装Prisma Client

npm install @prisma/client

生成Prisma Client

每次修改Schema后,需要重新生成Prisma Client:

npx prisma generate

使用Prisma Client

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

const prisma = new PrismaClient();

async function main() {
// 创建用户
const user = await prisma.user.create({
data: {
name: '张三',
email: 'zhangsan@example.com',
password: 'hashedpassword123'
}
});

// 创建带有关联的帖子
const post = await prisma.post.create({
data: {
title: 'Hello World',
content: '我的第一篇帖子',
published: true,
author: {
connect: { id: user.id }
}
}
});

// 查询帖子及其作者
const postsWithAuthors = await prisma.post.findMany({
where: {
published: true
},
include: {
author: true
}
});

console.log(postsWithAuthors);
}

main()
.catch(e => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});

查询操作

基本查询

// 查找所有记录
const users = await prisma.user.findMany();

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

// 排序和分页
const paginatedUsers = await prisma.user.findMany({
orderBy: {
createdAt: 'desc'
},
skip: 10,
take: 5
});

关联查询

// 包含关联数据
const usersWithPosts = await prisma.user.findMany({
include: {
posts: true
}
});

// 选择性包含关联数据
const usersWithPublishedPosts = await prisma.user.findMany({
include: {
posts: {
where: {
published: true
}
}
}
});

// 多层嵌套包含
const complexQuery = await prisma.user.findMany({
include: {
posts: {
include: {
comments: true
}
}
}
});

高级过滤

const filteredUsers = await prisma.user.findMany({
where: {
AND: [
{
name: {
contains: '张',
mode: 'insensitive'
}
},
{
OR: [
{
age: {
gte: 18
}
},
{
hasVerifiedAccount: true
}
]
}
]
}
});

更新操作

// 更新单个记录
const updatedUser = await prisma.user.update({
where: {
id: 1
},
data: {
name: '李四',
email: 'lisi@example.com'
}
});

// 条件更新多个记录
const updatedPosts = await prisma.post.updateMany({
where: {
authorId: 1
},
data: {
published: true
}
});

// 原子更新操作
const incrementLikes = await prisma.post.update({
where: {
id: 1
},
data: {
likes: {
increment: 1
}
}
});

删除操作

// 删除单个记录
const deletedUser = await prisma.user.delete({
where: {
id: 1
}
});

// 条件删除多个记录
const deletedPosts = await prisma.post.deleteMany({
where: {
authorId: 1,
published: false
}
});

Prisma的优缺点

优点

  1. 类型安全:自动生成TypeScript类型,提供编译时检查
  2. 直观的API:提供流畅的查询构建器API
  3. 强大的迁移工具:自动化数据库迁移管理
  4. 跨数据库支持:支持PostgreSQL、MySQL、SQLite、MongoDB等
  5. 性能优化:生成高效的SQL查询
  6. IDE支持:提供优秀的自动完成和类型提示

缺点

  1. 学习曲线:需要熟悉Prisma特有的Schema语法
  2. 生态系统相对较新:相比其他ORM工具,社区和插件生态相对较小
  3. 灵活性限制:对于极其复杂的SQL查询,可能需要回退到原始SQL

最佳实践

  1. 在应用启动时创建单个Prisma Client实例
  2. 使用事务处理需要原子性的操作
  3. 合理使用索引提升查询性能
  4. 使用Prisma Studio进行数据可视化和管理
  5. 对敏感操作使用审核日志
  6. 在生产环境中使用连接池优化性能

与其他ORM工具对比

相比Mongoose、Sequelize等其他ORM工具,Prisma的主要优势在于类型安全性、直观的API和强大的迁移工具。Mongoose更专注于MongoDB,提供了更多MongoDB特有功能,而Sequelize则提供了更传统的ORM体验,支持更多的数据库操作。选择哪种工具应根据项目需求、技术栈和团队偏好来决定。