9.1 核心概念
- 单例 PrismaClient
- 整个进程只应有一个
PrismaClient实例。多实例各建连接池,快速耗尽数据库连接数。 - 热重载连接泄漏
- 开发时 Next.js/Nodemon 频繁热重载模块,若每次都
new PrismaClient()会不断累积实例。用挂到globalThis的方式复用。 - 连接池(connection pool)
- Prisma 维护一组到数据库的复用连接,池大小由连接串的
connection_limit控制,默认与 CPU 相关。 - Serverless 连接风暴
- Lambda/函数每次冷启动新建连接,高并发时瞬间打爆数据库连接数。需外部连接池(PgBouncer)或 Accelerate。
- Prisma Accelerate
- 官方托管的全球连接池 + 查询缓存层,通过
prisma://连接,缓解 Serverless 连接风暴并加速边缘读取。 - driverAdapters
- 让 Prisma 用 JS 原生驱动(如
@prisma/adapter-neon、@prisma/adapter-pg)走 WASM 引擎,支持 Cloudflare Workers/Vercel Edge 等边缘环境。
9.2 单例封装(通用 + Next.js)
// lib/prisma.ts —— 兼容开发热重载的单例
import { PrismaClient } from "@prisma/client";
const globalForPrisma = globalThis as unknown as { prisma?: PrismaClient };
export const prisma =
globalForPrisma.prisma ??
new PrismaClient({ log: ["query", "warn", "error"] });
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
9.3 Next.js App Router
// app/users/page.tsx —— Server Component 直接查
import { prisma } from "@/lib/prisma";
export default async function Page() {
const users = await prisma.user.findMany({ take: 20 });
return <ul>{users.map((u) => <li key={u.id}>{u.email}</li>)}</ul>;
}
Prisma 不进浏览器
Prisma Client 只能在服务端运行(Server Component / Route Handler / Server Action)。别在 "use client" 组件里 import,会打包失败或泄漏连接串。
9.4 Express 集成
import express from "express";
import { prisma } from "./lib/prisma";
const app = express();
app.get("/users/:id", async (req, res) => {
const user = await prisma.user.findUnique({ where: { id: Number(req.params.id) } });
if (!user) return res.status(404).json({ error: "Not found" });
res.json(user);
});
// 优雅关闭:进程退出前断开
process.on("beforeExit", () => prisma.$disconnect());
9.5 NestJS 集成
// prisma.service.ts
import { Injectable, OnModuleInit } from "@nestjs/common";
import { PrismaClient } from "@prisma/client";
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
}
把 PrismaService 作为 provider 注入各 service,Nest 的 DI 天然保证单例。
9.6 Serverless 与连接池
# 直连数据库时限制连接数(配合外部 PgBouncer)
DATABASE_URL="postgresql://u:p@host:5432/db?connection_limit=1&pgbouncer=true"
| 部署形态 | 推荐做法 |
|---|---|
| 长驻服务(VM/容器) | 单例 + 合理 connection_limit |
| Serverless 函数 | PgBouncer / Accelerate,connection_limit=1 |
| Edge(Workers/Vercel Edge) | driverAdapters + Accelerate(prisma://) |
9.7 Edge:driverAdapter 示例
import { PrismaClient } from "@prisma/client";
import { PrismaNeon } from "@prisma/adapter-neon";
const adapter = new PrismaNeon({ connectionString: process.env.DATABASE_URL });
export const prisma = new PrismaClient({ adapter });
版本敏感
driverAdapters、Accelerate 的 API 与 preview flag 随版本演进较快。落地前请对照你所用 Prisma 版本的官方文档确认包名与配置。
9.8 小结与下一步
- 永远用单例 PrismaClient,开发环境挂
globalThis防热重载泄漏。 - Prisma 只在服务端跑;Next.js 在 Server 侧、Express 直接注入、NestJS 靠 DI。
- Serverless 用 PgBouncer/Accelerate 防连接风暴,Edge 用 driverAdapters。
- 最后一章讲 部署与工程化实战——迁移策略、seeding、调优、Docker、checklist。