实况足球2014手机版
437.86 MB · 2025-12-15
Prisma 是下一代 Node.js 和 TypeScript ORM。与传统的 ORM(如 TypeORM)不同,Prisma 不使用类(Classes)来映射数据库表,而是使用自定义的 Schema 语言来定义模型,并生成 类型安全(Type-safe) 的查询构建器(Client)。
Prisma 生态系统由三个主要工具组成:
在现有的 NestJS 项目中安装 Prisma CLI 和 Client:
# 安装 CLI (开发依赖)
pnpm add -D prisma
# 安装 Client (运行时依赖)
pnpm add @prisma/client
# 初始化 (生成 prisma 文件夹和 .env, prisma.config.ts)
npx prisma init
# 安装 dotenv 用于加载环境变量
pnpm add -D dotenv
Prisma 7 引入了 配置即代码 的理念,核心配置分散在以下文件中:
prisma.config.ts:Prisma 的主配置文件,负责指定 Schema 文件位置、配置迁移文件生成路径以及配置数据源连接。prisma/schema.prisma:指定数据源类型(Provider)、生成器(Generator)和定义数据模型(Models)。.env:存储环境变量(如 DATABASE_URL)。Prisma CLI 默认只读取此文件,但可以通过系统环境变量覆盖,或在 prisma.config.ts 中自定义加载逻辑。1. prisma.config.ts 示例:
import 'dotenv/config';
import { defineConfig, env } from 'prisma/config';
export default defineConfig({
// 1. 指定 schema 文件位置
schema: 'prisma/schema.prisma',
// 2. 配置迁移文件生成路径
migrations: {
path: 'prisma/migrations',
},
// 3. 配置数据源连接
// 这里使用 env() 函数读取环境变量,实现了配置与代码的分离
datasource: {
url: env('DATABASE_URL'),
},
});
2. prisma/schema.prisma 示例:
// 指定生成器
generator client {
provider = "prisma-client-js"
}
// 指定数据源类型 (注意:此处不再配置 url)
datasource db {
provider = "mysql"
}
// 定义 User 模型
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
为了在 NestJS 中高效使用,我们需要创建一个全局 Service 来管理连接生命周期,并在业务模块中注入使用。
步骤 1:创建全局 PrismaService
src/prisma/prisma.service.ts:
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
async onModuleInit() {
await this.$connect();
}
async onModuleDestroy() {
await this.$disconnect();
}
}
src/prisma/prisma.module.ts:
import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Global() // 设为全局模块,避免到处 import
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}
步骤 2:在业务模块中使用
假设有一个 UsersModule,你只需要在 Service 的构造函数中注入 PrismaService 即可。
src/users/users.service.ts:
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { User, Prisma } from '@prisma/client'; // 导入生成的类型
@Injectable()
export class UsersService {
constructor(private prisma: PrismaService) {}
async createUser(data: Prisma.UserCreateInput): Promise<User> {
return this.prisma.user.create({
data,
});
}
async findAll() {
return this.prisma.user.findMany();
}
}
nestjs-prisma)虽然本文推荐使用官方的手动集成方式以理解底层原理,但在生产环境中,建议选择社区成熟的封装库 nestjs-prisma。
PrismaModule 和 PrismaService,开箱即用。配置阶段 (prisma.config.ts):
prisma 命令时,它首先被加载。schema.prisma),去哪找迁移文件 (migrations),以及去哪找数据库连接串 (.env -> DATABASE_URL)。反向工程阶段 (Introspection, 可选):
npx prisma db pullprisma/schema.prisma 文件中,确保你的 Schema 定义与真实数据库保持同步。迁移同步阶段 (Migration/Sync):
npx prisma migrate dev 或 npx prisma db push 时,Prisma 会计算差异并同步到数据库。migrate dev:对比 schema.prisma 和 迁移历史(借助影子库)。生成 SQL 迁移文件并应用到数据库,适合团队协作。db push:对比 schema.prisma 和 数据库当前结构。忽略迁移历史,根据差异内容,直接将变更应用到数据库,适合快速开发。migrate dev:执行 本地新生成的 SQL 迁移文件。db push:执行 内存中即时计算出的变更 SQL。生成阶段 (CodeGen):
npx prisma generate 时(migrate dev 和 db push 默认都会自动触发此步),Prisma 读取 schema.prisma 中的 model User { ... }。User, UserCreateInput) 和 JavaScript 查询逻辑。node_modules/@prisma/client 目录中。schema.prisma 后必须重新运行 generate,否则你的代码里拿不到新字段的提示。运行阶段 (Runtime):
this.prisma.user.findMany() 时,PrismaService 实例(已在应用启动时连接数据库)会将 JS 对象转换成 SQL 语句发送给数据库,并将结果反序列化回 JS 对象。代码自动生成 (postinstall):
package.json 中配置 "postinstall": "prisma generate"。npm install 安装依赖后,会自动触发 prisma generate。这样确保 node_modules/@prisma/client 永远是最新的,你下载完项目就能直接跑,不用担心缺少 Prisma 类型代码。修改表结构的流程:
migrate dev):当你修改了 schema.prisma 后,需手动运行 npx prisma migrate dev。
prisma generate 重新生成 Client 代码。node_modules 更新,NestJS 热重载触发,IDE 获得新字段提示。db push):需手动运行 npx prisma db push。
prisma generate。运行时连接 (PrismaService):
2.3 节创建的 PrismaService 实现了 OnModuleInit 接口。npm run start:dev) 时,PrismaService 会自动调用 $connect() 建立数据库连接池。应用停止时自动断开。migrate dev 背后的黑盒机制Prisma Migrate 的核心逻辑是基于 Shadow Database(影子数据库) 来计算差异的。
当你运行 prisma migrate dev 时,Prisma 会在后台偷偷做这件事:
prisma/migrations 文件夹里所有的 SQL 文件,按顺序在这个影子库里执行一遍。执行完后,影子库的状态就是 “上一次迁移后的状态” (B)。schema.prisma (A) 和这个影子库 (B) 对比。prisma/migrations。结论:
prisma/migrations) 作为历史记录的依据。migrations 文件夹删了,Prisma 就失忆了,下次它就会认为你是从零开始,生成全量迁移。prisma/migrations 文件夹必须提交到 Git,它是项目源代码的重要组成部分。