NextJS 数据库 之 遇上Prisma ORM
- 前言
- 一、环境要求
- 二、概念介绍
- 1、Prisma Schema Language(PSL) 结构描述语言
- 1.1 概念
- 1.2 组成
- 1.2.1 Data Source 数据源
- 1.2.2 Generators 生成器
- 1.2.3 Data Model Definition 数据模型定义
- 字段(数据)类型和约束
- 关系(Relations)
- 枚举(Enum)
 
 
 
- 2、Prisma Client 数据交互接口
- 2.1 概念
- 2.2 使用示例
 
- 3、Prisma Migrate 迁移与种子
- 3.1 概念
- 3.2 迁移流程
- 3.3 数据库迁移(Migrate)
- 3.3 数据种子(Seeding)
 
- 4、Prisma CLI 命令行工具
- init
- generate
 
 
- 三、Next.js 中应用示例
- 1、全新项目示例
- 1.1 项目初始化
- 1.2 初始化Prisma ORM
- 1.3 数据迁移
- 1.4 播种数据(可选)
- 1.5 模拟业务
 
 
前言
在
Next.js全栈开发的时候不免要用到数据库,采用原生数据库语法可能还需要顾虑很多方面的问题(语法安全、原生语法麻烦/繁琐/复杂、更换数据库时的语法兼容等等),为了解决这类问题诞生了ORM(Object-Relational Mapping)数据访问方式技术及周边工具;
这里介绍一个易用又强大的ORM框架/工具库:Prisma ORM
官网:https://www.prisma.io/
GitHub:https://github.com/prisma/prisma
内容包含以下两个部分:
-  重点概念 - Prisma Schema Language (PSL).:用来描述数据库架构的语言
 
-  两个主要(常用)操作库 - Prisma Client:为 Node.js 和 TypeScript 自动生成类型安全的查询生成器
 可用于任何- Node.js或- TypeScript后端应用程序(包括无服务器应用程序和微服务)。
- Prisma Migrate:声明式数据建模和迁移系统
 主要用于生产部署、数据迁移等应用场景
 
-  附 - Prisma CLI:辅助快捷的操作命令工具
 
延展辅助(平台服务):
- Prisma Postgres[链接]:托管的 PostgreSQL 数据库服务
- Prisma Accelerate[链接]:针对现有数据库的完全托管的全局连接池和缓存层,可直接从 Prisma ORM 支持查询级缓存策略。
- Prisma Optimize[链接]:针对数据操作,基于AI进行优化分析服务
- Prisma Studio[链接]:用于查看和编辑等操作的数据库可视化GUI工具
一、环境要求
最新环境要求可前往官方文档:https://www.prisma.io/docs/orm/reference/system-requirements
软件:
| 工具 | 最低要求版本 | 
|---|---|
| Node.js | 18.8 / 20.9 / 22.11 | 
| TypeScript (可选) | 5.1.X | 
| Yarn (可选) | 1.19.2(当使用Yarn 1时) | 
操作系统:
Linux:
- OpenSSL 1.0.x、1.1.x 或 3.x
- zlib(libz.so.1)
- libgcc( libgcc_s.so.1)
- C 标准库(大多数 Linux 发行版上的 glibc 或 Alpine Linux 上的 musl libc)
Windows:
- Microsoft Visual C++ 可再发行组件 2015或必须安装更新版本
macOS:
- macOS 10.15 或更新版本
二、概念介绍
1、Prisma Schema Language(PSL) 结构描述语言
1.1 概念
Prisma Schema Language(简称:PSL) - Prisma ORM 的核心部分
用于定义数据库模型、关系、以及生成 Prisma Client 的配置文件。
- 【Prisma Schema 参数文档】:https://www.prisma.io/docs/orm/reference/prisma-schema-reference
想要将架构拆分为多个文件? Prisma ORM 5.15.0 及更高版本中的 prismaSchemaFolder 预览功能 支持多文件 Prisma Schema 。
它是一个声明式语言,通过定义 .prisma 文件来描述数据库结构和关系。
 Prisma Client将基于(PSL)生成数据库交互代码。
1.2 组成
- Data Source:数据库源(例如:- PostgreSQLor- MongoDB…)
- Generators:数据模型生成器(例如:Prisma Client)
- Data model definition:数据模型定义(例如,user数据表有哪些字段、分别什么数据类型等)
1.2.1 Data Source 数据源
定义数据库的连接信息,通常包括数据库的类型(例如PostgreSQL、MySQL、SQLite等)、连接URL、以及数据库的其他配置。
示例:
datasource db {provider = "postgresql" // 指定 PostgreSQL 作为数据库url      = env("DATABASE_URL") // 从环境变量 DATABASE_URL 获取连接字符串
}
1.2.2 Generators 生成器
定义生成器的配置,Prisma默认使用生成Prisma Client。
通常会在此配置生成的Prisma Client存放的位置,以及语言(TypeScript/JavaScript)。
示例:
generator client {provider = "prisma-client-js"output   = "./generated/client"
}
1.2.3 Data Model Definition 数据模型定义
定义数据库中的
实体(表)。每个model对应数据库中的一个表,表的字段对应model中的属性。
可以定义字段的类型、默认值、约束(如@id、@unique等)以及关系(如@relation)。
model User {id    Int    @id @default(autoincrement())email String @uniquename  Stringposts Post[]
}model Post {id      Int    @id @default(autoincrement())title   Stringcontent String?author  User   @relation(fields: [authorId], references: [id])authorId Int
}
字段(数据)类型和约束
每个字段可以指定数据类型,支持多种类型,如Int、String、Boolean、DateTime、Float、Decimal等。
 可以通过@default()设置默认值,@unique设置唯一约束,@id定义主键等。
- 更多内置约束:https://www.prisma.io/docs/orm/reference/prisma-schema-reference#attributes
model Post {id        Int      @id @default(autoincrement())title     Stringpublished Boolean  @default(false)createdAt DateTime @default(now())
}
关系(Relations)
PSL支持定义实体之间的关系。常见的关系包括一对一(1:1)、一对多(1:N)和多对多(M:N)。通过@relation定义。
- 更多关系说明:https://www.prisma.io/docs/orm/prisma-schema/data-model/relations
// 示例:一对多关系model User {id    Int    @id @default(autoincrement())posts Post[]
}model Post {id      Int    @id @default(autoincrement())userId  Intauthor  User   @relation(fields: [userId], references: [id])
}
枚举(Enum)
PSL还支持枚举类型,用于表示有多个固定选项的字段。
// 示例enum Role {USERADMINMODERATOR
}model User {id    Int    @id @default(autoincrement())name  Stringrole  Role
}
更多数据模型内容可以前往官方文档探索:https://www.prisma.io/docs/orm/prisma-schema/data-model
2、Prisma Client 数据交互接口
2.1 概念
Prisma Client是Prisma ORM的主要组成部分,它是一个自动生成的数据库查询客户端,用于与数据库进行交互。
提供一种类型安全的方式来执行数据库操作,简化与数据库的连接和操作。
- 【Prisma Client API文档】:https://www.prisma.io/docs/orm/reference/prisma-client-reference
关键特点:
- 自动生成:根据数据库模式(schema.prisma文件)自动生成一个类型安全的客户端库(代码)
- 类型安全:使用 TypeScript来生成类型定义,这意味着在开发过程中,可以获得类型推导和自动补全,数据操作无需手动编写原始SQL语法交由Prisma Client提供的API使用JavaScript/TypeScript中的类型安全语法
- 完善接口(API):包含CRUD、关联、分页和排序、事务操作等
- 数据库支持: PostgreSQL、MySQL、MariaDB、SQL Server、SQLite、CockroachDB、MongoDB各类主流数据库
2.2 使用示例
- 定义数据库模型(schema.prisma)
datasource db {provider = "postgresql"url      = env("DATABASE_URL")
}generator client {provider = "prisma-client-js"
}model User {id    Int    @id @default(autoincrement())name  Stringemail String @unique
}
- 模型构建
pnpx prisma generate
- 在代码中使用
import { PrismaClient } from '@prisma/client';const prisma = new PrismaClient();async function main() {const users = await prisma.user.findMany();console.log(users);
}main().catch(e => {throw e
}).finally(async () => {await prisma.$disconnect()
});3、Prisma Migrate 迁移与种子
3.1 概念
Prisma Migrate是Prisma ORM中用于数据库迁移的工具。
通过自动生成和执行 SQL 迁移脚本来管理数据库结构变化,同时确保数据库结构与Prisma Schema文件(schema.prisma)保持一致。
3.2 迁移流程

 通常的工作流程包括以下几个步骤:
- 修改 Prisma 模式:你在 schema.prisma文件中修改数据库模型。
- 创建迁移文件:运行 prisma migrate dev或prisma migrate create命令,自动生成迁移文件。
- 应用迁移:通过 prisma migrate deploy或prisma migrate dev将迁移应用到数据库。
- 查看迁移历史:Prisma 会在数据库中跟踪迁移历史,确保每次迁移都按顺序应用。
3.3 数据库迁移(Migrate)
3.3 数据种子(Seeding)
4、Prisma CLI 命令行工具
- 文档[英]
- 支持指令[英]
init
| 参数 | 默认 | 描述 | 
|---|---|---|
| --datasource-provider | postgresql | 指定块provider中字段的值datasource。选项包括sqlite、postgresql、mysql、和。sqlservermongodbcockroachdb | 
| --url | 定义自定义数据源 URL | |
| --with-model | 在初始 Prisma 模式中添加一个简单的用户模型。 自 5.14.0 版起可用。 | |
| --output | node_modules/.prisma/client | 指定生成的客户端的输出位置 | 
| --generator-provider | prisma-client-js | 定义要使用的生成器提供程序 | 
| --preview-feature | 定义要使用的预览功能 | 
示例:
pnpx prisma init --datasource-provider PostgreSQL
generate
| 参数 | 默认 | 描述 | 
|---|---|---|
| --no-engine | 生成不带附带引擎的 Prisma Client 以与Prisma Accelerate–data-proxy一起使用。与和互斥–accelerate。在 Prisma ORM 5.2.0 及更高版本中可用。 | |
| --no-hints | 生成 Prisma Client,但不会在终端上打印使用提示。在 Prisma ORM 5.16.0 及更高版本中可用。 | |
| --allow-no-models | 将生成 Prisma Client,但不生成任何模型 | |
| --watch | 监视schema.prisma文件并在文件更改时重新生成 Prisma Client | 
示例:
prisma generate
其他的后续再整理补充…
三、Next.js 中应用示例
以
Next.js+PostgreSQL组合为例!
node环境:
- node:v20.17.0
- pnpm:9.15.3
1、全新项目示例
1.1 项目初始化
- react:^19.0.0
- next:15.1.4
- pg:^8.13.1
- @prisma/client:^6.2.1
pnpx create-next-app@latest// 安装时,将看到以下提示:
✔ What is your project named? … .
✔ Would you like to use TypeScript? … Yes
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … Yes
✔ Would you like your code inside a `src/` directory? … No
✔ Would you like to use App Router? (recommended) … Yes
✔ Would you like to use Turbopack for `next dev`? … No
✔ Would you like to customize the import alias (`@/*` by default)? … No
增加依赖包:pg、@prisma/client
pnpm add pg @prisma/client
1.2 初始化Prisma ORM
// 初始化兼容PostgreSQL驱动数据库
pnpx prisma init --datasource-provider PostgreSQL// 将看到以下提示:
✔ Your Prisma schema was created at prisma/schema.prismaYou can now open it in your favorite editor.warn You already have a .gitignore file. Don't forget to add `.env` in it to not commit any private information.Next steps:
1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started
2. Run prisma db pull to turn your database schema into a Prisma schema.
3. Run prisma generate to generate the Prisma Client. You can then start querying your database.
4. Tip: Explore how you can extend the ORM with scalable connection pooling, global caching, and real-time database events. Read: https://pris.ly/cli/beyond-ormMore information in our documentation:
https://pris.ly/d/getting-started
至此,基础环境搞定,接下来重点查看编辑两个文件:.env和prisma/schema.prisma
 
 在.env文件中,重点设置DATABASE_URL的值,用于建立数据库连接的配置
DATABASE_URL="postgresql://[username]:[password]@[ip|domain]:[port|5432]/[database][?param1=value1¶m2=value2&...]"
在prisma/schema.prisma文件中,对生成器、数据模型进行配置
generator client {provider = "prisma-client-js"output   = "./client"   // 配置生成器的代码生成位置(相对schema.prisma文件所在目录)
}datasource db {provider = "postgresql"url      = env("DATABASE_URL")
}// 以下部分均为数据模型构建配置
model User {id    Int    @id @default(autoincrement())email String @uniquename  Stringposts Post[]
}model Post {id        Int     @id @default(autoincrement())title     Stringcontent   Stringpublished Booleanuser      User    @relation(fields: [userId], references: [id])userId    Int
}
完成以上配置后,开始生成Prisma客户端代码:
// 生成Prisma客户端
pnpx prisma generate// 将看到以下提示:
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma✔ Generated Prisma Client (v6.2.1) to ./prisma/client in 24msStart by importing your Prisma Client (See: https://pris.ly/d/importing-client)Tip: Need your database queries to be 1000x faster? Accelerate offers you that and more: https://pris.ly/tip-2-accelerate

1.3 数据迁移
将数据模型推送到数据库中
// 模型推送
pnpx prisma db push// 将看到以下提示:
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "xxxx", schema "public" at "xxxx:5432"🚀  Your database is now in sync with your Prisma schema. Done in 6.22s✔ Generated Prisma Client (v6.2.1) to ./prisma/client in 28ms
1.4 播种数据(可选)
添加
ts-node和@types/node到开发依赖项pnpm add -D ts-node @types/nodePs:非
TypeScript项目需要增加typescript依赖包
在prisma目录下创建一个seed.ts文件,写入播种数据
// 导入 PrismaClient(注:pnpx prisma generate生成的代码)
import { PrismaClient } from './client'// 创建 PrismaClient 实例
const prisma = new PrismaClient()// 定义 main 函数
async function main() {// 使用 upsert 方法创建或更新用户const alice = await prisma.user.upsert({where: { email: 'alice@prisma.io' },update: {},create: {email: 'alice@prisma.io',name: 'Alice',posts: {create: {title: 'Check out Prisma with Next.js',content: 'https://www.prisma.io/nextjs',published: true,},},},})// 创建另一个用户const bob = await prisma.user.upsert({where: { email: 'bob@prisma.io' },update: {},create: {email: 'bob@prisma.io',name: 'Bob',posts: {create: [{title: 'Follow Prisma on Twitter',content: 'https://twitter.com/prisma',published: true,},{title: 'Follow Nexus on Twitter',content: 'https://twitter.com/nexusgql',published: true,},],},},})console.log({ alice, bob })
}// 执行 main 函数并处理错误
main().then(async () => {await prisma.$disconnect()}).catch(async (e) => {console.error(e)await prisma.$disconnect()process.exit(1)})
在package.json文件中新增以下配置,告诉prisma播种文件所在位置及其他配置信息
{// ....."prisma": {"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"},// .....
}
将种子数据推送上数据库里
// 种子推送
pnpx prisma db seed// 将看到以下提示:
Environment variables loaded from .env
Running seed command `ts-node --compiler-options {"module":"CommonJS"} prisma/seed.ts` ...
{alice: { id: 1, email: 'alice@prisma.io', name: 'Alice' },bob: { id: 2, email: 'bob@prisma.io', name: 'Bob' }
}🌱  The seed command has been executed.

1.5 模拟业务
创建一个api接口
GET /api/users用于获取用户表所有数据
1、实例化 Prisma 客户端
在prisma目录创建一个db.ts文件,用于实例化
 
// file:/prisma/db.tsimport {PrismaClient} from './client'const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }export const prisma = globalForPrisma.prisma || new PrismaClient()if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prismaexport default prisma
2、创建数据API接口
 
"use server";import {NextResponse} from 'next/server'
// 导入客户端实例
import prisma from "@/prisma/db"export async function GET() {// 使用findMany方法获取user表相关数据const allUsers = await prisma.user.findMany();return NextResponse.json({message: 'Hello World',data: allUsers}, {status: 200});
}
3、测试获取是否正常
 
有何不足之处欢迎评论区或者私信我