⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议
Skip to content

4.2.1 增删改查的背后——CRUD 操作:Create/Read/Update/Delete 基础

一句话破题

CRUD 是数据库操作的四个基本动作——几乎所有的业务逻辑都可以归结为这四种操作的组合。

CRUD 四大操作

操作SQLPrisma说明
CreateINSERTcreate新增数据
ReadSELECTfindMany/findUnique查询数据
UpdateUPDATEupdate修改数据
DeleteDELETEdelete删除数据

Create:创建数据

SQL 写法

sql
INSERT INTO users (email, name) VALUES ('user@example.com', '张三');

Prisma 写法

typescript
const user = await prisma.user.create({
  data: {
    email: 'user@example.com',
    name: '张三'
  }
})

批量创建

typescript
const users = await prisma.user.createMany({
  data: [
    { email: 'user1@example.com', name: '用户1' },
    { email: 'user2@example.com', name: '用户2' }
  ]
})

Read:查询数据

查询单条

typescript
const user = await prisma.user.findUnique({
  where: { id: 'xxx' }
})

查询多条

typescript
const users = await prisma.user.findMany({
  where: { name: { contains: '张' } },
  orderBy: { createdAt: 'desc' },
  take: 10,
  skip: 0
})

关联查询

typescript
const userWithPosts = await prisma.user.findUnique({
  where: { id: 'xxx' },
  include: { posts: true }
})

Update:更新数据

更新单条

typescript
const user = await prisma.user.update({
  where: { id: 'xxx' },
  data: { name: '新名字' }
})

批量更新

typescript
const count = await prisma.user.updateMany({
  where: { role: 'USER' },
  data: { status: 'ACTIVE' }
})

条件更新(upsert)

typescript
// 存在则更新,不存在则创建
const user = await prisma.user.upsert({
  where: { email: 'user@example.com' },
  update: { name: '更新后的名字' },
  create: { email: 'user@example.com', name: '新用户' }
})

Delete:删除数据

删除单条

typescript
const user = await prisma.user.delete({
  where: { id: 'xxx' }
})

批量删除

typescript
const count = await prisma.user.deleteMany({
  where: { status: 'DELETED' }
})

软删除 vs 硬删除

类型说明适用场景
硬删除真正从数据库删除临时数据、日志数据
软删除标记为已删除,保留数据用户数据、订单数据

软删除实现

prisma
model User {
  id        String    @id
  deletedAt DateTime? // null 表示未删除
}
typescript
// 软删除
await prisma.user.update({
  where: { id: 'xxx' },
  data: { deletedAt: new Date() }
})

// 查询时过滤已删除
await prisma.user.findMany({
  where: { deletedAt: null }
})

操作的原子性

数据库保证单个 CRUD 操作是原子的:

  • 要么完全成功
  • 要么完全失败
  • 不会出现"改了一半"的情况

如果需要多个操作一起成功或失败,需要使用事务(4.2.3 节详述)。

避坑指南

  1. 避免 N+1 查询:使用 include 一次性查询关联数据

    typescript
    // 错误:N+1 查询
    const users = await prisma.user.findMany()
    for (const user of users) {
      const posts = await prisma.post.findMany({ where: { authorId: user.id } })
    }
    
    // 正确:一次查询
    const users = await prisma.user.findMany({ include: { posts: true } })
  2. 删除前检查关联:外键约束可能阻止删除

    typescript
    // 先删除关联数据,或配置级联删除
    await prisma.post.deleteMany({ where: { authorId: userId } })
    await prisma.user.delete({ where: { id: userId } })
  3. 更新时注意并发:多人同时更新同一条数据可能产生冲突

本节小结

  • CRUD 是数据库的四种基本操作
  • Prisma 提供了类型安全的 CRUD API
  • 软删除比硬删除更安全
  • 注意避免 N+1 查询问题