NestJS业务逻辑层与Prisma详解
学习目标:理解业务逻辑层架构、掌握 Controller 参数传递、熟练使用 Prisma Client 的 CRUD API。
一、业务逻辑层架构流程
1.1 完整的请求处理流程
code
前端请求
↓
Controller(控制器层)
↓ 参数解析
Service(业务逻辑层)
↓ 数据操作
Prisma Client(ORM 层)
↓ SQL 生成
Database(数据库层)
↓ 数据返回
Prisma Client
↓ 对象映射
Service
↓ 数据处理
Controller
↓ 响应封装
前端响应1.2 各层职责详解
| 层级 | 职责 | 关键内容 |
|---|---|---|
| Controller | 接收请求、参数解析、响应封装 | 获取请求参数、调用 Service、返回数据 |
| Service | 业务逻辑处理、数据转换 | 实现具体业务逻辑、调用 Prisma |
| Prisma | ORM 操作、SQL 生成 | 数据库 CRUD 操作、对象映射 |
| Database | 数据持久化、数据查询 | 数据存储、事务处理 |
1.3 参数传递流程
code
Controller 层:
│
├── 获取请求参数
│ ├── @Query() - 查询参数
│ ├── @Param() - 路径参数
│ ├── @Body() - 请求体参数
│ └── @Headers() - 请求头参数
│
├── 调用 Service 方法
│ └── this.homeService.create(createDto)
│
└── 返回响应
└── return result
Service 层:
│
├── 接收 Controller 传递的参数
│ └── async create(createDto: CreateHomeResourceDto)
│
├── 调用 Prisma 操作数据库
│ └── return this.prisma.homeResources.create({ data: createDto })
│
└── 返回数据给 Controller
└── return result二、Controller 参数获取方式
2.1 不同 HTTP 方法的参数获取
code
HTTP 方法与参数类型:
│
├── GET 请求
│ ├── 主要参数:@Query() 查询参数
│ ├── 示例:GET /home-resources?page=1&limit=10
│ └── 使用场景:查询列表、过滤、分页
│
├── POST 请求
│ ├── 主要参数:@Body() 请求体参数
│ ├── 示例:POST /home-resources { "title": "xxx" }
│ └── 使用场景:创建资源
│
├── PUT 请求
│ ├── 主要参数:@Body() 请求体参数 + @Param() 路径参数
│ ├── 示例:PUT /home-resources/1 { "title": "xxx" }
│ └── 使用场景:整体更新资源
│
├── PATCH 请求
│ ├── 主要参数:@Body() 请求体参数 + @Param() 路径参数
│ ├── 示例:PATCH /home-resources/1 { "title": "xxx" }
│ └── 使用场景:部分更新资源
│
└── DELETE 请求
├── 主要参数:@Param() 路径参数
├── 示例:DELETE /home-resources/1
└── 使用场景:删除资源2.2 参数组合使用
常见组合方式:
typescript
// 1. POST + 路径参数 + Body 参数
@Post(':id/comments')
async addComment(
@Param('id') id: string,
@Body() createCommentDto: CreateCommentDto,
) {
return this.service.addComment(+id, createCommentDto);
}
// 2. GET + 路径参数 + Query 参数
@Get(':id/posts')
async getUserPosts(
@Param('id') id: string,
@Query('page') page: number,
@Query('limit') limit: number,
) {
return this.service.getUserPosts(+id, page, limit);
}
// 3. PUT + 路径参数 + Body 参数
@Put(':id')
async update(
@Param('id') id: string,
@Body() updateDto: UpdateDto,
) {
return this.service.update(+id, updateDto);
}2.3 参数传递到 Service 层
Controller 层:
typescript
@Controller('home')
export class HomeController {
constructor(private readonly homeService: HomeService) {}
// GET 查询列表
@Get()
async findAll(
@Query('page') page: number = 1,
@Query('limit') limit: number = 10,
) {
return this.homeService.findAll(page, limit);
}
// GET 查询单条
@Get(':id')
async findOne(@Param('id') id: string) {
return this.homeService.findOne(+id);
}
// POST 创建
@Post()
async create(@Body() createDto: CreateHomeResourceDto) {
return this.homeService.create(createDto);
}
// PUT 更新
@Put(':id')
async update(
@Param('id') id: string,
@Body() updateDto: UpdateHomeResourceDto,
) {
return this.homeService.update(+id, updateDto);
}
// DELETE 删除
@Delete(':id')
async remove(@Param('id') id: string) {
return this.homeService.remove(+id);
}
}Service 层:
typescript
@Injectable()
export class HomeService {
constructor(private prisma: PrismaService) {}
// 查询列表
async findAll(page: number, limit: number) {
const skip = (page - 1) * limit;
return this.prisma.homeResources.findMany({
skip,
take: limit,
orderBy: { order: 'asc' },
});
}
// 查询单条
async findOne(id: number) {
return this.prisma.homeResources.findUnique({
where: { id },
});
}
// 创建
async create(createDto: CreateHomeResourceDto) {
return this.prisma.homeResources.create({
data: createDto,
});
}
// 更新
async update(id: number, updateDto: UpdateHomeResourceDto) {
return this.prisma.homeResources.update({
where: { id },
data: updateDto,
});
}
// 删除
async remove(id: number) {
return this.prisma.homeResources.delete({
where: { id },
});
}
}三、Prisma Client CRUD API 详解
3.1 Prisma API 总览
code
Prisma Client API 分类:
│
├── 查询操作(Read)
│ ├── findMany() # 查询多条记录
│ ├── findFirst() # 查询第一条记录
│ ├── findUnique() # 查询唯一记录(基于唯一字段)
│ ├── findFirstOrThrow() # 查询第一条或抛异常
│ └── findUniqueOrThrow() # 查询唯一记录或抛异常
│
├── 创建操作(Create)
│ ├── create() # 创建单条记录
│ └── createMany() # 批量创建记录
│
├── 更新操作(Update)
│ ├── update() # 更新单条记录
│ ├── updateMany() # 批量更新记录
│ └── upsert() # 更新或创建
│
├── 删除操作(Delete)
│ ├── delete() # 删除单条记录
│ └── deleteMany() # 批量删除记录
│
└── 计数操作(Count)
└── count() # 统计记录数3.2 查询操作详解
3.2.1 findMany - 查询多条记录
基本用法:
typescript
// 查询所有记录
const allUsers = await prisma.user.findMany();
// 带条件查询
const activeUsers = await prisma.user.findMany({
where: {
status: 'active',
},
});
// 分页查询
const users = await prisma.user.findMany({
skip: 0, // 跳过多少条
take: 10, // 获取多少条
});
// 排序查询
const users = await prisma.user.findMany({
orderBy: {
createdAt: 'desc',
},
});
// 选择字段
const users = await prisma.user.findMany({
select: {
id: true,
name: true,
email: true,
},
});
// 组合查询
const users = await prisma.user.findMany({
where: {
status: 'active',
age: {
gte: 18, // age >= 18
},
},
skip: 0,
take: 10,
orderBy: {
createdAt: 'desc',
},
select: {
id: true,
name: true,
email: true,
},
});查询条件操作符:
| 操作符 | 说明 | 示例 |
|---|---|---|
equals | 等于 | { status: { equals: 'active' } } |
not | 不等于 | { status: { not: 'inactive' } } |
in | 在列表中 | { id: { in: [1, 2, 3] } } |
notIn | 不在列表中 | { id: { notIn: [1, 2, 3] } } |
lt | 小于 | { age: { lt: 18 } } |
lte | 小于等于 | { age: { lte: 18 } } |
gt | 大于 | { age: { gt: 18 } } |
gte | 大于等于 | { age: { gte: 18 } } |
contains | 包含 | { name: { contains: 'Tom' } } |
startsWith | 以...开头 | { name: { startsWith: 'T' } } |
endsWith | 以...结尾 | { email: { endsWith: '@gmail.com' } } |
3.2.2 findFirst - 查询第一条记录
基本用法:
typescript
// 查询第一条记录
const firstUser = await prisma.user.findFirst();
// 查询符合条件的第一条记录
const firstActiveUser = await prisma.user.findFirst({
where: {
status: 'active',
},
});
// 查询并排序
const latestUser = await prisma.user.findFirst({
orderBy: {
createdAt: 'desc',
},
});
// 查询年龄最大的用户
const oldestUser = await prisma.user.findFirst({
orderBy: {
age: 'desc',
},
});3.2.3 findUnique - 查询唯一记录
适用场景:
- 查询主键(ID)
- 查询唯一字段(设置了
@unique的字段)
基本用法:
typescript
// 根据 ID 查询
const user = await prisma.user.findUnique({
where: {
id: 1,
},
});
// 根据唯一字段查询
const user = await prisma.user.findUnique({
where: {
email: 'tom@example.com',
},
});
// 根据唯一字段组合查询(联合唯一索引)
const user = await prisma.user.findUnique({
where: {
email_phone: {
email: 'tom@example.com',
phone: '1234567890',
},
},
});Schema 定义唯一字段:
prisma
model User {
id Int @id @default(autoincrement())
email String @unique // 唯一字段
phone String @unique // 唯一字段
username String @unique // 唯一字段
// 联合唯一索引
@@unique([email, phone], name: "email_phone")
}返回值说明:
- 找到记录:返回对象
- 未找到记录:返回
null
3.2.4 findFirstOrThrow 和 findUniqueOrThrow
与 findFirst 和 findUnique 的区别:
| 方法 | 找到记录 | 未找到记录 |
|---|---|---|
findFirst() | 返回对象 | 返回 null |
findFirstOrThrow() | 返回对象 | 抛出异常 |
findUnique() | 返回对象 | 返回 null |
findUniqueOrThrow() | 返回对象 | 抛出异常 |
使用场景:
typescript
// 使用 findUniqueOrThrow 查询用户,不存在则抛异常
const user = await prisma.user.findUniqueOrThrow({
where: { id: 1 },
});
// 配合 try-catch 处理
try {
const user = await prisma.user.findUniqueOrThrow({
where: { id: 999 },
});
return user;
} catch (error) {
throw new NotFoundException('用户不存在');
}异常类型:
PrismaClientKnownRequestError- 错误代码:
P2025(记录不存在)
3.3 创建操作详解
3.3.1 create - 创建单条记录
基本用法:
typescript
// 创建用户
const user = await prisma.user.create({
data: {
name: 'Tom',
email: 'tom@example.com',
age: 25,
},
});
// 创建并返回指定字段
const user = await prisma.user.create({
data: {
name: 'Tom',
email: 'tom@example.com',
},
select: {
id: true,
name: true,
email: true,
},
});3.3.2 createMany - 批量创建记录
基本用法:
typescript
// 批量创建
const result = await prisma.user.createMany({
data: [
{ name: 'Tom', email: 'tom@example.com' },
{ name: 'Jerry', email: 'jerry@example.com' },
{ name: 'Alice', email: 'alice@example.com' },
],
});
// 返回值:{ count: 3 } 创建的记录数参数说明:
typescript
interface CreateManyOptions {
data: Array<any>; // 要创建的数据数组
skipDuplicates?: boolean; // 是否跳过重复记录(默认 false)
}3.4 更新操作详解
3.4.1 update - 更新单条记录
基本用法:
typescript
// 更新用户
const user = await prisma.user.update({
where: { id: 1 },
data: {
name: 'Tom Updated',
age: 26,
},
});
// 更新并返回指定字段
const user = await prisma.user.update({
where: { id: 1 },
data: {
name: 'Tom Updated',
},
select: {
id: true,
name: true,
},
});更新操作符:
typescript
// 数字字段增加
await prisma.user.update({
where: { id: 1 },
data: {
age: {
increment: 1, // age = age + 1
},
},
});
// 数字字段减少
await prisma.user.update({
where: { id: 1 },
data: {
age: {
decrement: 1, // age = age - 1
},
},
});
// 数字字段乘法
await prisma.user.update({
where: { id: 1 },
data: {
age: {
multiply: 2, // age = age * 2
},
},
});
// 设置字段值
await prisma.user.update({
where: { id: 1 },
data: {
name: {
set: 'New Name', // name = 'New Name'
},
},
});3.4.2 updateMany - 批量更新记录
基本用法:
typescript
// 批量更新
const result = await prisma.user.updateMany({
where: {
status: 'pending',
},
data: {
status: 'active',
},
});
// 返回值:{ count: 5 } 更新的记录数3.4.3 upsert - 更新或创建
upsert() 的作用:
- 如果记录存在,则更新
- 如果记录不存在,则创建
基本用法:
typescript
const user = await prisma.user.upsert({
where: { email: 'tom@example.com' },
update: {
name: 'Tom Updated',
age: 26,
},
create: {
email: 'tom@example.com',
name: 'Tom',
age: 25,
},
});参数说明:
typescript
interface UpsertOptions {
where: { ... }; // 查询条件(必传)
update: { ... }; // 更新数据(必传)
create: { ... }; // 创建数据(必传)
select?: { ... }; // 选择返回字段(可选)
include?: { ... }; // 关联查询(可选)
}upsert() 执行逻辑:
code
upsert 执行流程:
│
├── 第一步:根据 where 条件查询记录
│
├── 第二步:判断记录是否存在
│ ├── 存在 → 执行 update 操作
│ └── 不存在 → 执行 create 操作
│
└── 第三步:返回操作后的记录使用场景:
typescript
// 场景 1:用户首次登录或更新信息
const user = await prisma.user.upsert({
where: { email: 'tom@example.com' },
update: {
lastLoginAt: new Date(),
},
create: {
email: 'tom@example.com',
name: 'Tom',
lastLoginAt: new Date(),
},
});
// 场景 2:商品浏览次数或创建浏览记录
const view = await prisma.productView.upsert({
where: {
productId_userId: {
productId: 1,
userId: 1,
},
},
update: {
viewCount: {
increment: 1,
},
},
create: {
productId: 1,
userId: 1,
viewCount: 1,
},
});3.5 删除操作详解
3.5.1 delete - 删除单条记录
基本用法:
typescript
// 删除用户
const user = await prisma.user.delete({
where: { id: 1 },
});
// 删除并返回指定字段
const user = await prisma.user.delete({
where: { id: 1 },
select: {
id: true,
name: true,
},
});注意:
- 如果记录不存在,会抛出异常
- 如果有外键约束,需要先删除关联记录
3.5.2 deleteMany - 批量删除记录
基本用法:
typescript
// 删除所有符合条件的记录
const result = await prisma.user.deleteMany({
where: {
status: 'inactive',
},
});
// 返回值:{ count: 5 } 删除的记录数
// 删除所有记录(危险操作)
const result = await prisma.user.deleteMany();3.6 计数操作
count() - 统计记录数:
typescript
// 统计所有记录
const count = await prisma.user.count();
// 返回值:{ count: 100 }
// 统计符合条件的记录
const activeCount = await prisma.user.count({
where: {
status: 'active',
},
});四、Prisma API 对比总结
4.1 查询方法对比
| 方法 | 返回值 | 记录不存在 | 使用场景 |
|---|---|---|---|
findMany() | 数组 | 返回 [] | 查询列表 |
findFirst() | 对象或 null | 返回 null | 查询第一条 |
findUnique() | 对象或 null | 返回 null | 查询唯一记录 |
findFirstOrThrow() | 对象 | 抛异常 | 查询第一条或报错 |
findUniqueOrThrow() | 对象 | 抛异常 | 查询唯一记录或报错 |
4.2 CRUD 方法对比
| 方法 | 单条/批量 | 返回值 | 说明 |
|---|---|---|---|
create() | 单条 | 创建的对象 | 创建一条记录 |
createMany() | 批量 | { count: number } | 批量创建 |
update() | 单条 | 更新后的对象 | 更新一条记录 |
updateMany() | 批量 | { count: number } | 批量更新 |
upsert() | 单条 | 创建或更新后的对象 | 更新或创建 |
delete() | 单条 | 删除的对象 | 删除一条记录 |
deleteMany() | 批量 | { count: number } | 批量删除 |
4.3 Prisma API 最佳实践
1. 选择合适的查询方法:
typescript
// 不推荐:使用 findMany 查询单条
const users = await prisma.user.findMany({
where: { id: 1 },
take: 1,
});
// 推荐:使用 findUnique 查询单条
const user = await prisma.user.findUnique({
where: { id: 1 },
});2. 使用 findUniqueOrThrow 处理不存在的情况:
typescript
// 不推荐:手动判断 null
const user = await prisma.user.findUnique({ where: { id: 1 } });
if (!user) {
throw new NotFoundException('用户不存在');
}
// 推荐:使用 findUniqueOrThrow
try {
const user = await prisma.user.findUniqueOrThrow({ where: { id: 1 } });
return user;
} catch (error) {
throw new NotFoundException('用户不存在');
}3. 使用 select 优化查询性能:
typescript
// 不推荐:查询所有字段
const users = await prisma.user.findMany();
// 推荐:只查询需要的字段
const users = await prisma.user.findMany({
select: {
id: true,
name: true,
email: true,
},
});4. 使用 upsert 简化逻辑:
typescript
// 不推荐:先查询再判断
const user = await prisma.user.findUnique({ where: { email } });
if (user) {
await prisma.user.update({
where: { email },
data: { lastLoginAt: new Date() },
});
} else {
await prisma.user.create({
data: { email, lastLoginAt: new Date() },
});
}
// 推荐:使用 upsert
const user = await prisma.user.upsert({
where: { email },
update: { lastLoginAt: new Date() },
create: { email, lastLoginAt: new Date() },
});五、完整实战示例
5.1 完整的 Service 实现
typescript
// src/modules/home/home.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { CreateHomeResourceDto } from './dto/create-home-resource.dto';
import { UpdateHomeResourceDto } from './dto/update-home-resource.dto';
@Injectable()
export class HomeService {
constructor(private prisma: PrismaService) {}
// 查询列表(分页)
async findAll(page: number = 1, limit: number = 10) {
const skip = (page - 1) * limit;
const [data, total] = await Promise.all([
this.prisma.homeResources.findMany({
skip,
take: limit,
orderBy: { order: 'asc' },
}),
this.prisma.homeResources.count(),
]);
return {
data,
meta: {
total,
page,
limit,
totalPages: Math.ceil(total / limit),
},
};
}
// 查询单条
async findOne(id: number) {
const resource = await this.prisma.homeResources.findUnique({
where: { id },
});
if (!resource) {
throw new NotFoundException('资源不存在');
}
return resource;
}
// 创建
async create(createDto: CreateHomeResourceDto) {
return this.prisma.homeResources.create({
data: createDto,
});
}
// 更新
async update(id: number, updateDto: UpdateHomeResourceDto) {
// 先检查是否存在
await this.findOne(id);
return this.prisma.homeResources.update({
where: { id },
data: updateDto,
});
}
// 删除
async remove(id: number) {
// 先检查是否存在
await this.findOne(id);
return this.prisma.homeResources.delete({
where: { id },
});
}
// 批量更新排序
async updateOrder(orders: Array<{ id: number; order: number }>) {
const updates = orders.map(({ id, order }) =>
this.prisma.homeResources.update({
where: { id },
data: { order },
}),
);
return Promise.all(updates);
}
}5.2 DTO 定义
typescript
// src/modules/home/dto/create-home-resource.dto.ts
export class CreateHomeResourceDto {
title: string;
subtitle?: string;
url?: string;
image?: string;
desc?: string;
module?: string;
type?: string;
icon?: string;
order?: number;
}
// src/modules/home/dto/update-home-resource.dto.ts
import { PartialType } from '@nestjs/mapped-types';
import { CreateHomeResourceDto } from './create-home-resource.dto';
export class UpdateHomeResourceDto extends PartialType(CreateHomeResourceDto) {}5.3 使用示例
typescript
// 查询示例
const resources = await this.prisma.homeResources.findMany({
where: {
module: 'home',
},
orderBy: [
{ order: 'asc' },
{ createdAt: 'desc' },
],
select: {
id: true,
title: true,
image: true,
},
});
// 创建示例
const resource = await this.prisma.homeResources.create({
data: {
title: '新资源',
subtitle: '副标题',
url: 'https://example.com',
module: 'home',
order: 100,
},
});
// 更新示例
const updated = await this.prisma.homeResources.update({
where: { id: 1 },
data: {
title: '更新后的标题',
order: {
increment: 1, // order = order + 1
},
},
});
// 删除示例
const deleted = await this.prisma.homeResources.delete({
where: { id: 1 },
});
// upsert 示例
const resource = await this.prisma.homeResources.upsert({
where: { id: 1 },
update: { title: '更新标题' },
create: { title: '新标题' },
});六、Prisma Client API 速查表
6.1 查询 API 速查
code
Prisma 查询 API 速查:
│
├── findMany()
│ ├── 查询多条记录
│ ├── 返回数组
│ └── 未找到返回 []
│
├── findFirst()
│ ├── 查询第一条记录
│ ├── 返回对象或 null
│ └── 可配合 orderBy 使用
│
├── findUnique()
│ ├── 查询唯一记录(基于 ID 或 unique 字段)
│ ├── 返回对象或 null
│ └── 只能用于 @unique 或 @@unique 字段
│
├── findFirstOrThrow()
│ ├── 查询第一条记录
│ ├── 返回对象
│ └── 未找到抛异常
│
└── findUniqueOrThrow()
├── 查询唯一记录
├── 返回对象
└── 未找到抛异常6.2 CRUD API 速查
code
Prisma CRUD API 速查:
│
├── create(data)
│ └── 创建单条记录,返回对象
│
├── createMany({ data: [] })
│ └── 批量创建,返回 { count: number }
│
├── update({ where, data })
│ └── 更新单条记录,返回对象
│
├── updateMany({ where, data })
│ └── 批量更新,返回 { count: number }
│
├── upsert({ where, update, create })
│ ├── 记录存在:更新
│ ├── 记录不存在:创建
│ └── 返回对象
│
├── delete({ where })
│ └── 删除单条记录,返回对象
│
├── deleteMany({ where })
│ └── 批量删除,返回 { count: number }
│
└── count({ where })
└── 统计记录数,返回 { count: number }6.3 查询条件速查
code
Prisma 查询条件操作符:
│
├── 比较操作
│ ├── equals # 等于
│ ├── not # 不等于
│ ├── in # 在列表中
│ ├── notIn # 不在列表中
│ ├── lt # 小于
│ ├── lte # 小于等于
│ ├── gt # 大于
│ └── gte # 大于等于
│
├── 字符串操作
│ ├── contains # 包含
│ ├── startsWith # 以...开头
│ ├── endsWith # 以...结尾
│ └── mode # 模式(default/insensitive)
│
├── 逻辑操作
│ ├── AND # 且
│ ├── OR # 或
│ └── NOT # 非
│
└── 更新操作
├── set # 设置值
├── increment # 增加值
├── decrement # 减少值
├── multiply # 乘以值
└── divide # 除以值七、常见问题与解决方案
7.1 记录不存在如何处理?
问题:使用 findUnique() 查询记录,返回 null 如何处理?
方案一:使用 findUniqueOrThrow:
typescript
try {
const user = await this.prisma.user.findUniqueOrThrow({
where: { id: 1 },
});
return user;
} catch (error) {
throw new NotFoundException('用户不存在');
}方案二:手动判断:
typescript
const user = await this.prisma.user.findUnique({
where: { id: 1 },
});
if (!user) {
throw new NotFoundException('用户不存在');
}
return user;7.2 如何实现分页查询?
typescript
async findAll(page: number = 1, limit: number = 10) {
const skip = (page - 1) * limit;
const [data, total] = await Promise.all([
this.prisma.user.findMany({
skip,
take: limit,
orderBy: { createdAt: 'desc' },
}),
this.prisma.user.count(),
]);
return {
data,
meta: {
total,
page,
limit,
totalPages: Math.ceil(total / limit),
},
};
}7.3 如何优化查询性能?
1. 使用 select 只查询需要的字段:
typescript
const users = await this.prisma.user.findMany({
select: {
id: true,
name: true,
email: true,
},
});2. 使用索引:
prisma
model User {
id Int @id @default(autoincrement())
email String @unique // 自动创建索引
name String
@@index([name]) // 手动创建索引
}3. 避免查询所有字段:
typescript
// 不推荐
const users = await this.prisma.user.findMany();
// 推荐
const users = await this.prisma.user.findMany({
select: { id: true, name: true },
});八、学习要点总结
8.1 核心知识点
code
本节核心知识点:
│
├── 业务逻辑层架构
│ ├── Controller → Service → Prisma → Database
│ ├── 参数传递流程
│ └── 各层职责划分
│
├── Controller 参数获取
│ ├── GET → @Query()
│ ├── POST → @Body()
│ ├── PUT → @Body() + @Param()
│ └── DELETE → @Param()
│
├── Prisma Client API
│ ├── 查询:findMany、findFirst、findUnique
│ ├── 创建:create、createMany
│ ├── 更新:update、updateMany、upsert
│ └── 删除:delete、deleteMany
│
└── 最佳实践
├── 选择合适的查询方法
├── 使用 findUniqueOrThrow 处理不存在
├── 使用 select 优化性能
└── 使用 upsert 简化逻辑8.2 学习路径规划
code
学习路径:
│
├── 第一阶段:理解概念(1 天)
│ ├── 理解业务逻辑层架构
│ ├── 理解参数传递流程
│ └── 了解 Prisma Client API 分类
│
├── 第二阶段:实践使用(2-3 天)
│ ├── 实现完整的 CRUD 接口
│ ├── 熟练使用查询条件操作符
│ └── 实现分页查询
│
└── 第三阶段:深入应用(持续)
├── 关联查询(下一节)
├── 事务处理
└── 性能优化8.3 重要程度标注
code
重要程度说明:
│
├── 必须掌握
│ ├── 业务逻辑层架构流程
│ ├── Controller 参数获取方式
│ ├── Prisma Client CRUD API
│ └── findUnique、upsert 的使用
│
├── 重要
│ ├── 参数组合使用
│ ├── 查询条件操作符
│ ├── 分页查询实现
│ └── 性能优化技巧
│
└── 了解
├── findFirstOrThrow
├── findUniqueOrThrow
└── 批量操作 API重要提示:这一节是业务逻辑层和 Prisma CRUD 操作的核心内容,理解参数传递流程、熟练使用 Prisma Client API,对实际项目开发非常重要!特别是要掌握 findUnique 和 upsert 的使用,这在实际项目中非常实用!
下一节预告:下一节将学习 Prisma 的关联查询,包括一对一、一对多、多对多关系的处理。