目录
- 前言
- [数据库与 Prisma](#数据库与 Prisma)
-
- 为什么我们需要数据库?
- [为什么选择 PostgreSQL + Prisma?](#为什么选择 PostgreSQL + Prisma?)
- [先认识一下 Prisma 7](#先认识一下 Prisma 7)
- 开发环境搭建
- 本课总结
课程:《外包项目管理平台・全栈实战课》
本课目标:从零搭出项目的数据层,完成 PostgreSQL 连接、Prisma 7 配置,并创建第一张业务表。
前言
上一课,我们先没有急着写代码,而是把整个系统看了一遍。
我们最终要做的,不是一个简单的 CRUD 后台,而是一套完整的外包项目管理平台。
它包含:
- 登录认证
- 组织与员工
- 角色与权限
- 工作流
- 客户管理
- 商机管理
- 合同管理
- 项目管理
- 项目预算
- 里程碑
- 任务执行
- 质量管理
- 运维管理
- 附件管理
这些功能看起来很多,但从软件的底层来看,都离不开一个东西:
数据。
例如:
"部门管理"其实是在管理部门数据。
"员工管理"是在管理员工数据。
"客户管理"是在管理客户数据。
"合同管理"是在管理合同数据。
"项目管理"是在管理项目数据。
所以,真正开始开发之前,我们首先要解决一个问题:
这些数据到底存在哪里?
这就是本课要解决的问题。
数据库与 Prisma
为什么我们需要数据库?
如果把一个企业数字化系统比作一栋房子,那么:
- 前端页面是房子的门窗
- 后端代码是房子的水电
- 数据库就是房子的地基
页面可以重新设计,代码可以不断迭代,但是企业真正长期沉淀下来的,是数据库中的业务数据。
例如:
text
部门
员工
角色
客户
商机
合同
项目
任务
这些数据会不断产生、修改、关联。
因此,我们不能简单地把数据写在代码里,也不能依赖浏览器临时保存。
我们需要一个真正的数据库。
本课程选择:
PostgreSQL
而程序与 PostgreSQL 之间,再增加一个数据访问层:
Prisma
最终形成:
text
Next.js
│
▼
Prisma
│
▼
PostgreSQL
│
▼
企业业务数据
为什么选择 PostgreSQL + Prisma?
数据库有很多选择。
例如:
- MySQL
- PostgreSQL
- SQL Server
- MongoDB
本课程选择 PostgreSQL,主要不是因为它"唯一正确",而是因为它非常适合我们后面的企业级系统。
我们的系统会大量涉及:
- 一对多关系
- 多对多关系
- 权限关系
- 流程关系
- 项目关系
- 数据约束
- 事务
这些都是典型的关系型数据场景。
所以我们使用 PostgreSQL。
但是还有一个问题:
JavaScript / TypeScript 程序,怎么操作 PostgreSQL?
传统方式可以直接写 SQL:
sql
SELECT * FROM dept;
但是在一个大型项目中,如果所有代码都直接手写 SQL,会产生大量重复工作,同时也容易出现类型错误。
所以我们引入 Prisma。
Prisma 可以理解成:
TypeScript 和数据库之间的一座桥。
例如数据库里有一张:
text
Dept
Prisma 会让我们可以直接使用:
ts
db.dept.findMany()
而不是每次都自己拼 SQL。
更重要的是,它可以让数据库结构和 TypeScript 类型建立联系。
这就是我们本课程选择 Prisma 的核心原因。
先认识一下 Prisma 7
这里需要特别说明一个版本问题。
本课程采用:
Prisma 7
Prisma 7 和很多旧教程中的 Prisma 写法存在明显区别。
如果你在网上搜索 Prisma 教程,很容易看到这样的写法:
prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
这是旧版本教程中非常常见的配置方式。
而 Prisma 7 的配置方式发生了变化。
现在:
text
schema.prisma
主要负责描述:
数据库是什么结构
而:
text
prisma.config.ts
负责描述:
Prisma 从哪里连接数据库
也就是说:
text
schema.prisma
↓
描述数据模型
prisma.config.ts
↓
描述数据库连接配置
另外,Prisma 7 在运行时推荐通过 Driver Adapter 连接数据库。
本课程使用:
text
@prisma/adapter-pg
连接 PostgreSQL。
最终的数据访问结构是:
text
Next.js
│
▼
lib/db.ts
│
├── PrismaClient
│
└── PrismaPg Adapter
│
▼
PostgreSQL
理解这个结构,比记住几个命令更加重要。
开发环境搭建
创建 Next.js 项目
先在硬盘空间里创建一个文件夹,表示整体的工程目录,可以命名为project

在地址栏里输入cmd

输入如下命令
bash
pnpm create next-app@latest outsourcing-pm-case

选择推进的配置即可

然后进入项目:

bash
cd outsourcing-pm
启动:
bash
pnpm dev

浏览器访问:
text
http://localhost:3000
能够看到 Next.js 页面,就说明第一步完成。

安装 Prisma 7
环境安装好之后,我们就可以先用编程IDE来安装后续步骤,这里我用trae作为演示
打开trae之后,点击文件下的打开文件夾

选择我们刚刚安装好的工程目录

然后点击查看,选择终端

在终端里安装数据库相关依赖。

bash
pnpm add -D prisma@7
pnpm add @prisma/client@7 @prisma/adapter-pg pg
pnpm add -D dotenv tsx @types/pg
这里我们明确锁定 Prisma 7。
检查版本:
bash
pnpm prisma -v

确认 Prisma CLI 是 7.x。
注意:本课程的代码是按照 Prisma 7 的配置方式编写的,不要直接套用网上针对 Prisma 6 或更早版本的教程。
如果 pnpm 阻止构建脚本
部分 pnpm 环境下,安装依赖时可能出现:
text
ERR_PNPM_IGNORED_BUILDS
例如:
text
Ignored build scripts:
prisma
@prisma/engines
esbuild
这不是 Prisma 本身报错,而是 pnpm 的安全机制阻止依赖执行构建脚本。
可以根据当前 pnpm 版本的提示,对相关依赖进行批准。
例如:
bash
pnpm approve-builds

根据终端提示选择需要批准的依赖。这里需要按空格键选中批准的依赖

然后重新安装:
bash
pnpm install
最后验证:
bash
pnpm prisma -v
如果能够正常输出 Prisma 7 的版本号,就可以继续。
创建 PostgreSQL 数据库
接下来准备数据库。
首先确保 PostgreSQL 已经安装并运行。
我们不建议让业务程序直接使用 PostgreSQL 超级用户。
因此,为本项目创建一个专用用户。
进入 PostgreSQL:
bash
psql -U postgres

执行:
sql
CREATE USER pm_user_case WITH PASSWORD '123456';
CREATE DATABASE outsourcing_pm_case OWNER pm_user_case;
GRANT ALL PRIVILEGES ON DATABASE outsourcing_pm_case TO pm_user_case;

这里需要理解三个概念:
text
pm_user_case
↓
数据库用户
outsourcing_pm_case
↓
本项目数据库
PostgreSQL
↓
数据库服务器
也就是说:
一个企业系统并不是"装了 PostgreSQL 就结束了",而是需要明确数据库、用户以及权限之间的关系。
测试数据库连接
可以直接使用:
bash
psql -U pm_user_case -d outsourcing_pm_case -h localhost

输入密码。
如果能够进入:
text
outsourcing_pm_case=>
说明 PostgreSQL 已经准备完成。
退出:
sql
\q
初始化 Prisma
回到 Next.js 项目:
bash
pnpm prisma init
正常情况下会生成 Prisma 配置文件和 schema 文件。

项目结构逐渐变成:
text
outsourcing-pm
├─ app/
├─ prisma/
│ └─ schema.prisma
├─ prisma.config.ts
├─ .env
├─ package.json
└─ ...
现在开始出现三个非常重要的文件:
text
.env
prisma.config.ts
prisma/schema.prisma
它们分别负责不同的事情。
配置数据库连接
打开:
text
.env
配置:
env
DATABASE_URL="postgresql://pm_user_case:123456@localhost:5432/outsourcing_pm_case"

注意:
.env是配置文件,不要提交到 Git 仓库。
理解 prisma.config.ts
打开:
text
prisma.config.ts
确认配置类似:
ts
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
这里有一个非常重要的认识。
以前我们容易把:
text
数据库连接
+
数据库结构
混在一起理解。
现在可以明确拆开:
text
prisma.config.ts
│
└── 我去哪里找数据库?
schema.prisma
│
└── 数据库里面应该有什么?
这个分层思维,在后面的工程开发中非常重要。
认识 schema.prisma
打开:
text
prisma/schema.prisma
先写最基本的结构:
prisma
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
datasource db {
provider = "postgresql"
}
这里有两个核心配置。
generator
prisma
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
它告诉 Prisma:
根据我们的数据模型生成 TypeScript 数据库客户端。
生成后的客户端会放到:
text
app/generated/prisma
datasource
prisma
datasource db {
provider = "postgresql"
}
它告诉 Prisma:
我们使用的是 PostgreSQL。
注意这里没有再写:
prisma
url = env("DATABASE_URL")
数据库连接地址由:
text
prisma.config.ts
负责。
本课总结
到这里,我们已经完成了整个数据底座的第一次搭建。
回顾一下刚才做的事情:
创建 Next.js 项目
↓
安装 Prisma 7
↓
准备 PostgreSQL
↓
配置数据库连接
↓
初始化 Prisma
↓
定义 schema
现在我们的项目已经具备了:
Next.js
│
▼
Prisma 7
│
▼
PostgreSQL