在 Next.js 16 TypeScript 项目中配置 Prisma 7
学习如何在 Next.js 16 应用中安装、配置 Prisma 7 并将其与 PostgreSQL 集成,同时构建单例客户端以避免连接泄漏。
本指南将展示如何在基于Next.js 16的应用中集成Prisma 7,使其能够与PostgreSQL数据库交互,同时使用TypeScript和pnpm作为包管理工具。
步骤1:添加Prisma相关包
pnpm add prisma @prisma/client @prisma/adapter-pg
- prisma — 用于执行迁移、生成客户端代码以及管理数据结构的命令行工具。
- @prisma/client — 由Prisma生成的客户端库,应用程序代码可直接调用它。
- @prisma/adapter-pg — Prisma 7引入的PostgreSQL驱动适配器,用于连接Postgres数据库。
安装好这三个包后,就可以开始配置Prisma环境了。
步骤2:初始化Prisma
pnpm dlx prisma init
运行此命令会生成开始使用所需的基线文件和文件夹。
prisma.config.ts
prisma/
└── schema.prisma
了解 prisma.config.ts
该文件包含了Prisma运行所需的配置,包括它如何连接到数据库以及客户端生成器的行为方式。
import "dotenv/config";
import { defineConfig } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: process.env["DATABASE_URL"],
},
});
了解 schema.prisma
任何计划存储在PostgreSQL中的表最终都会以模型定义的形式出现在这里。
generator client {
provider = "prisma-client"
output = "../lib/generated/prisma"
}
datasource db {
provider = "postgresql"
}
// models that You want to create
步骤3:将Prisma指向您的数据库
Prisma在能够与数据库通信之前需要一个连接字符串。您可以从Neon这样的托管服务获取该字符串,或者通过Docker在本地运行Postgres实例来获得。
DATABASE_URL="postgresql://username:password@localhost:5432/my_database"
一旦设置了这个环境变量,Prisma就能连接到您的数据库。
步骤4:定义初始模型
在架构中至少存在一个模型之前,无法生成 Prisma Client。
由于此时数据库仍为空,需添加一个最简单的占位模型,以便 Prisma 有内容可处理。
model Test {
id Int @id @default(autoincrement())
}
这里的目标并非创建有实际意义的表——只是为生成器提供一个有效的架构作为构建基础。
第 5 步:应用首个迁移
接下来,通过执行迁移操作将该架构转换为真实的数据库表。
pnpm dlx prisma migrate dev
这条命令会自动处理几项任务:
- 生成一个新的迁移文件。
- 将该迁移应用到已配置的数据库中。
- 使实际数据库结构与
schema.prisma中声明的内容保持同步。
一旦操作成功完成,数据库中就会存在 Test 表。
第6步:生成Prisma客户端
Prisma 7的一个显著变化是,客户端不再自动为您生成。
现在您需要手动触发生成过程。
pnpm dlx prisma generate dev
完成此步骤后,Prisma会生成一个针对您所定义的架构的全类型客户端。
该客户端提供了查询和修改数据所需的所有方法。
generated/
└── prisma/
在您的架构中定义的每个模型现在都会作为独立的类型化TypeScript API呈现。
第7步:构建单例Prisma客户端
最佳实践是不要在每次请求时都创建新的Prisma客户端,而应在整个应用中重用同一个实例。
File: lib/prisma.ts
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "./generated/prisma/client";
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
function createPrismaClient() {
const url = process.env.DATABASE_URL;
if (!url) {
throw new Error("DATABASE_URL is not set");
}
const adapter = new PrismaPg({ connectionString: url });
return new PrismaClient({ adapter });
}
export const prisma = globalForPrisma.prisma ?? createPrismaClient();
if (process.env.NODE_ENV !== "production") {
globalForPrisma.prisma = prisma;
}
为何此处需要单例
在开发过程中,Next.js会不断热加载模块。
如果每次重新加载时都创建一个新的 PrismaClient 实例,那么打开的数据库连接数将会远远超出预期。
如果不加以控制,最终会出现类似以下的错误:
Too many database connections
使用单例模式可以确保在整个应用程序运行期间只存在一个 Prisma Client 实例。
这正是 Prisma 本身为 Next.js 项目推荐的方案。
第8步:在应用程序中处处使用该客户端
有了这个共享的客户端实例后,你就可以从项目的任何地方导入它。
import { prisma } from "@/lib/prisma";
这样一来,所有的服务器组件、API 路由或服务器动作都可以直接访问数据库。
如需了解此设置的更多细节,请参阅 prisma.io/docs/guides/nextjs 上的 Prisma 官方 Next.js 集成文档。
相关阅读
- 构建可复用的 Next.js 启动模板以省略样板代码 — 了解一名开发者如何用一系列越来越完善的极简型、商店页面和着陆页启动模板来替代重复的 Next.js 清理工作。
- 从 Prisma 迁移到 Drizzle:六个月回顾 — 一名开发者分享了将 PostgreSQL TypeScript 技术栈从 Prisma 更改为 Drizzle ORM 的实际测试结果及权衡考量。