1. 前言
在业务逻辑中,数据库操作是非常常见的一部分。前端应用中展示的数据通常都来源于数据库,通过数据库的读写操作,能够为用户提供所需的信息和功能。
Prisma 是一个现代化的 ORM 工具,简化了数据库操作,并提供了强类型支持和自动生成的数据库模型。现在将探讨如何将 Prisma 集成到项目中,并如何利用其功能来高效管理数据库。
Prisma 目前支持 PostgreSQL、MySQL、SQL Server、SQLite、MongoDB 和 CockroachDB。
这里我们以 PostgreSQL 为例。
欢迎加入技术交流群。
- NestJS 🧑🍳 厨子必修课(一):后端的本质
- NestJS 🧑🍳 厨子必修课(二):项目创建
- NestJS 🧑🍳 厨子必修课(三):控制器
- NestJS 🧑🍳 厨子必修课(四):服务类
- NestJS 🧑🍳 厨子必修课(五):Prisma 集成(上)
- NestJS 🧑🍳 厨子必修课(六):Prisma 集成(下)
- NestJS 🧑🍳 厨子必修课(七):管道
- NestJS 🧑🍳 厨子必修课(八):异常过滤器
2. Prisma 初始化
2.1 安装 prisma
npm install prisma -D
2.2 初始化 prisma 设置
npx prisma init
运行完成后,将会在根目录下生成 prisma 目录,里面有一个 schema.prisma 文件用于配置数据库连接和数据库模型,同时在根目录还生成了 .env 文件,用于编写环境变量。
2.3 安装 prisma 客户端
为了能够在 Nest 应用中与数据库进行交互,还要使用 Prisma Client,因此也要安装:
npm install @prisma/client
3. 配置数据库连接
在连接之前需要启动一个数据库,这里使用 docker compose 来实现。
3.1 启动数据库实例
使用 docker compose 创建一个 PostgreSQL 的数据库实例:
# docker-compose.yml
version: '3.8'
services:
cook-api-1-postgres:
container_name: cook-api-1-postgres
image: postgres:14-alpine
restart: always
environment:
- POSTGRES_USER=cook
- POSTGRES_PASSWORD=cookpassword
volumes:
- cook-api-1-data:/var/lib/postgresql/data
ports:
- '5432:5432'
volumes:
cook-api-1-data:
在终端输入以下命令:
docker compose up -d
输入 docker ps
可以看到 cook-api-1-postgres 数据库实例正在运行:
3.2 配置数据库环境变量
在 prisma/schema.prisma 文件中配置 PostgreSQL 数据库连接。找到 datasource 部分并进行如下配置:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
这表示 prisma 的数据源来自 postgresql,位置从 .env 文件中的 DATABASE_URL 变量中读取。
然后,在项目根目录下的 .env 文件中添加数据库连接 URL:
DATABASE_URL="postgresql://cook:cookpassword@localhost:5432/dev-db"
意思是连接到 localhost:5432 的 dev-db
数据库,用户名为 cook
、密码为 cookpassword
,这和 docker-compose.yml 中的变量是一致的,否则登录不进去。
3.3 生成模型与迁移
假设佟掌柜让秀才记录的用户信息如下:
User 表 Excel 模拟
这些内容在数据库中是一张 User 表,我们需要在 schema.prisma 文件中定义这样的模型:
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
createdAt DateTime @default(now())
}
model User
:模型的名称为 User。id
:这是一个整型(Int
)字段,用来唯一标识每个用户。它被标记为@id
,这意味着它是这个模型的主键。@default(autoincrement())
表示每当创建一个新记录时,这个字段的值会自动递增。email
:这是一个字符串类型(String
)的字段,用来存储用户的电子邮件地址。@unique
修饰符确保了每个用户的电子邮件地址是唯一的,即不允许有重复的电子邮件地址。name
:这是一个可选的字符串字段,用来存储用户的名字。问号(?
)表示这个字段可以为空。createdAt
:这是一个日期时间类型的字段,用来记录用户创建的时间。@default(now())
表示每当创建一个新用户时,这个字段会自动设置为当前的日期和时间。
⚠️ 注意:以上属于 Prisma 的模型定义方式,具体可参阅 Prisma 官网。
定义好的模型和数据库还没有关联,因此需要迁移数据库,这样数据库里才有 User 表。
迁移数据库:
npx prisma migrate dev --name init
migrate
: 这是 Prisma CLI 的一个子命令,用于管理数据库迁移。数据库迁移是数据库架构变更的过程,它允许你将数据库模型的更改应用到实际的数据库中。dev
: 这是迁移命令的一个选项,它告诉 Prisma 创建一个开发迁移。开发迁移通常用于本地开发环境,它们不会应用到生产数据库上,而是用于测试和开发目的。--name init
: 这是命令的一个参数,用于给迁移命名。在这个例子中,迁移被命名为init
,这通常表示这是一个初始化迁移,可能是为了设置数据库的初始状态。
这个命令会根据当前模型生成 SQL 迁移文件,并自动应用到数据库中。现在数据库就和我们的 schema 文件同步完成了,还自动生成了 Prisma Client。
⚠️ 注意:我们也可以使用 npx prisma generate
来手动生成 Prisma Client。
通过 VSC 插件 SQLTools 连接数据库可以看到 User 表已经成功创建了:
4. 数据播种
为了验证 Nest 应用能否成功集成了 Prisma,我们将通过 Prisma Client 进行数据播种,看能否与数据库交互。
4.1 可视化数据库
现在运行一下命令可以在 5555 端口看到数据库的内容:
npx prisma studio
打开后,User 表的记录数量为 0。
4.2 创建 seed 文件
首先在 prisma 目录下新建 seed.ts:
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
// 删除现有的所有数据 (可选)
await prisma.user.deleteMany();
// 创建种子数据
const users = await prisma.user.createMany({
data: [
{
email: 'alice@example.com',
name: 'Alice',
},
{
email: 'bob@example.com',
name: 'Bob',
},
{
email: 'charlie@example.com',
name: 'Charlie',
},
],
});
console.log(`Seeded ${users.count} users`);
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
调用 prisma 客户端实例(prisma
)批量创建 user 用户,这些数据将会真实地记录到数据库中,创建完成后断开数据库连接。
4.3 运行 seed 脚本
在 package.json 中加入脚本:
{
"scripts": {
+ "seed": "ts-node prisma/seed.ts",
+ "studio": "prisma studio"
}
}
然后运行:
npm run seed
接着运行:
npm run studio
可以看到 User 表中已经有内容了。(id
从 4 开始是因为笔者之前执行过一次了)
5. 总结
通过本篇内容,大家已经学会了如何初始化 Prisma、配置数据库连接以及数据播种,此时 NestJS 已经可以和数据库交互了,在下篇中将会进一步介绍如何在业务逻辑处理中使用 Prisma 来解决实际问题。