8.1 核心概念
- Client Extensions($extends)
- 新一代扩展机制,取代旧的
$use中间件。可扩展四类组件,返回一个新的扩展后 Client(原 Client 不变,类型自动增强)。 - result 组件
- 给查询结果加计算字段:声明依赖的真实字段,用
compute派生出虚拟字段(如fullName),查询时按需计算。 - model 组件
- 给某个 model 加自定义方法,如
prisma.user.signup(...),把领域逻辑挂到模型上。 - query 组件
- 拦截并改写查询:在操作执行前后插入逻辑(如自动加过滤条件、审计日志),实现软删除的关键。
- 软删除(soft delete)
- 不物理删除行,而是打
deletedAt标记;查询默认过滤掉已删记录。可用 query 扩展统一实现。 - JSON 字段查询
- 对
Json(Postgres jsonb)字段做路径过滤:path+equals/string_contains/array_contains等。 - 全文搜索(full-text search)
- PostgreSQL/MySQL 上的
search过滤器,基于数据库原生全文索引做关键词检索(需开启 preview 或对应支持)。
8.2 计算字段:result 扩展
const xprisma = prisma.$extends({
result: {
user: {
fullName: {
needs: { firstName: true, lastName: true },
compute(u) {
return `${u.firstName} ${u.lastName}`;
},
},
},
},
});
const u = await xprisma.user.findFirst();
console.log(u?.fullName); // 类型安全的虚拟字段
8.3 模型方法:model 扩展
const xprisma = prisma.$extends({
model: {
user: {
async signup(email: string) {
return prisma.user.create({ data: { email } });
},
},
},
});
await xprisma.user.signup("new@x.com");
8.4 软删除:query 扩展
const xprisma = prisma.$extends({
query: {
user: {
// 把 delete 改写为 update deletedAt
async delete({ args, query }) {
return prisma.user.update({ ...args, data: { deletedAt: new Date() } });
},
// 查询自动过滤已删
async findMany({ args, query }) {
args.where = { ...args.where, deletedAt: null };
return query(args);
},
},
},
});
$extends 不变异原 Client
$extends 返回新 Client,类型自动带上扩展。可链式叠加多个扩展,也可抽成可复用的 Prisma.defineExtension(...) 包。
8.5 JSON 字段查询
// metadata Json? 字段
await prisma.product.findMany({
where: {
metadata: {
path: ["specs", "color"],
equals: "red",
},
},
});
// 数组包含
await prisma.product.findMany({
where: { metadata: { path: ["tags"], array_contains: ["sale"] } },
});
8.6 全文搜索
// schema: previewFeatures = ["fullTextSearchPostgres"](视版本)
await prisma.post.findMany({
where: { title: { search: "prisma & orm" } },
orderBy: { _relevance: { fields: ["title"], search: "prisma", sort: "desc" } },
});
依数据库而异
全文搜索能力与语法随 provider 和 Prisma 版本变化,可能需在 generator 里开 previewFeatures,并在库中建对应全文索引。生产前请核对当前版本文档。
8.7 多 schema 组织
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
schemas = ["auth", "blog"] // 多个 PG schema
}
model User {
id Int @id @default(autoincrement())
@@schema("auth")
}
model Post {
id Int @id @default(autoincrement())
@@schema("blog")
}
此外 schema.prisma 支持拆分为多文件(prisma/schema/*.prisma),便于大项目按领域组织模型。
8.8 小结与下一步
$extends四组件:result(计算字段)、model(方法)、query(拦截改写)、client(顶层方法)。- 软删除靠 query 扩展改写 delete/find;JSON 用
path过滤;全文用search。 - 大项目用多 PG schema 与多文件 schema 组织模型。
- 下一章讲 与框架集成——Next.js/Express/NestJS 与 Serverless。