4.2.1 增删改查的背后——CRUD 操作:Create/Read/Update/Delete 基础
一句话破题
CRUD 是数据库操作的四个基本动作——几乎所有的业务逻辑都可以归结为这四种操作的组合。
CRUD 四大操作
| 操作 | SQL | Prisma | 说明 |
|---|---|---|---|
| Create | INSERT | create | 新增数据 |
| Read | SELECT | findMany/findUnique | 查询数据 |
| Update | UPDATE | update | 修改数据 |
| Delete | DELETE | delete | 删除数据 |
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 节详述)。
避坑指南
避免 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 } })删除前检查关联:外键约束可能阻止删除
typescript// 先删除关联数据,或配置级联删除 await prisma.post.deleteMany({ where: { authorId: userId } }) await prisma.user.delete({ where: { id: userId } })更新时注意并发:多人同时更新同一条数据可能产生冲突
本节小结
- CRUD 是数据库的四种基本操作
- Prisma 提供了类型安全的 CRUD API
- 软删除比硬删除更安全
- 注意避免 N+1 查询问题
