Chapter 05

Prisma Client 基础 CRUD

用类型安全的 Client 做增删改查:create、findUnique/findMany、update、upsert、delete,配合 select/include 精确取数。

5.1 CRUD 方法一览

create / createMany
插入单条 / 批量插入。data 指定字段值,返回新建记录(createMany 只返回计数)。
findUnique
按唯一字段(@id/@unique)查单条,命中返回记录、未命中返回 null
findFirst / findMany
按任意条件查第一条 / 多条,支持 whereorderBytakeskip
update / updateMany
按唯一键更新单条 / 按条件批量更新,where 定位、data 设值。
upsert
存在则更新、不存在则创建,一次原子操作,参数含 where/create/update
delete / deleteMany
按唯一键删单条 / 按条件批量删除。
select vs include
select 挑选返回哪些字段(白名单,可含关系);include 在返回全部标量字段基础上额外带上关系。二者不能对同一层同时用。

5.2 Create

const user = await prisma.user.create({
  data: {
    email: "bob@example.com",
    name: "Bob",
    posts: {                          // 嵌套创建关系
      create: [{ title: "First post" }],
    },
  },
});

// 批量插入,跳过唯一冲突
await prisma.user.createMany({
  data: [{ email: "c@x.com" }, { email: "d@x.com" }],
  skipDuplicates: true,
});

5.3 Read:findUnique / findMany

const u = await prisma.user.findUnique({
  where: { email: "bob@example.com" },
});

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

// 找不到就抛错的变体
const must = await prisma.user.findUniqueOrThrow({ where: { id: 1 } });

5.4 select 与 include

// select:只要 id + email,返回类型收窄为 { id; email }
const slim = await prisma.user.findMany({
  select: { id: true, email: true },
});

// include:全部字段 + 关联 posts
const withPosts = await prisma.user.findMany({
  include: { posts: true },
});

// select 里嵌套 select,精确到关系字段
const nested = await prisma.user.findMany({
  select: {
    id: true,
    posts: { select: { title: true }, where: { published: true } },
  },
});
类型随查询而变

select/include 后,返回值 TypeScript 类型会精确反映你选了哪些字段与关系——多选了报错、少选了访问不到,全在编译期。

5.5 Update 与 Upsert

const updated = await prisma.user.update({
  where: { id: 1 },
  data: { name: "Bobby" },
});

// 数值原子自增
await prisma.post.update({
  where: { id: 1 },
  data: { views: { increment: 1 } },
});

const up = await prisma.user.upsert({
  where: { email: "e@x.com" },
  create: { email: "e@x.com", name: "Eve" },
  update: { name: "Eve" },
});

5.6 Delete

await prisma.user.delete({ where: { id: 1 } });

const { count } = await prisma.post.deleteMany({
  where: { published: false },
});

5.7 复用生成类型

Prisma 生成的类型可直接 import,也可用工具类型按查询推导:

import { Prisma, User } from "@prisma/client";

// 精确推导"带 posts 的 User"类型
type UserWithPosts = Prisma.UserGetPayload<{
  include: { posts: true };
}>;

// 复用输入类型做函数签名
function buildWhere(w: Prisma.UserWhereInput) { /* ... */ }
结果处理惯例

findUnique/findFirst 可能返回 null,务必判空;需要"查不到即报错"用 ...OrThrow 变体,异常为 PrismaClientKnownRequestError(code P2025)。

5.8 小结与下一步