当前位置: 首页 > news >正文

Prisma----科普一个ORM框架

Prisma 是什么?

简单来说,Prisma 是一个次世代的 Node.js 和 TypeScript ORM。ORM 的全称是 Object-Relational Mapping(对象关系映射),它的核心作用是在您的代码(通常是面向对象的)和关系型数据库(如 MySQL, PostgreSQL)之间建立一座桥梁。

1. 一个比喻:代码与数据库之间的“高级翻译官”

您可以把 Prisma 想象成一位精通多国语言的高级翻译官,驻扎在您的应用程序和数据库之间。

  • 您的代码(比如 NestJS):说的是 TypeScript/JavaScript 这种“面向对象的语言”。您想的是:“给我一个用户对象(User Object)”。
  • 数据库(比如 MySQL):说的是 SQL 这种“关系型语言”。它想的是:“执行 SELECT * FROM users WHERE id = 1;”。

Prisma 的工作就是将您代码中的 prisma.user.findUnique(...) 这句“对象语言”,精确无误地翻译成数据库能懂的最高效的 SQL 语句,然后再将数据库返回的表格数据,翻译回您代码中类型完整的 TypeScript 对象。

Prisma 的三大核心组件

Prisma 不是一个单一的库,而是一个工具集,主要由三个部分组成:

  1. Prisma Schema (模式文件)
    • 这是一个名为 schema.prisma 的文件,是您项目的唯一真实数据源 (Single Source of Truth)
    • 您在这里用一种非常简单直观的语言 (PSL - Prisma Schema Language) 来定义您的数据模型、数据库连接信息以及客户端生成器。它就像是数据库的蓝图。
  1. Prisma Client (客户端)
    • 这是您在代码中实际使用的部分。它是一个根据您的 schema.prisma 文件自动生成的、完全类型安全的查询构建器
    • 当您在 schema.prisma 中定义了一个 User 模型后,Prisma Client 就会自动拥有 prisma.user.create(), prisma.user.findMany() 等方法,并且所有这些方法的参数和返回值都带有完整的 TypeScript 类型。这就是为什么您在 VS Code 中能获得极致的自动补全体验。
  1. Prisma Migrate (迁移工具)
    • 这是一个强大的数据库迁移工具。当您修改了 schema.prisma 文件(比如给 User 模型增加一个 age 字段)后,您只需运行一个命令 (prisma migrate dev),Prisma Migrate 就会自动比较您的 schema 和数据库的当前状态,生成必要的 SQL 迁移文件(例如 ALTER TABLE "User" ADD COLUMN "age" INTEGER;),并安全地更新您的数据库结构,同时保留现有数据。

Prisma 的底层原理

了解了它的组成部分后,我们来看看它们是如何协同工作的。

流程一:prisma generate - 从蓝图到可执行代码

当您编写好 schema.prisma 文件并运行 npx prisma generate 命令时,背后发生了几件关键的事情:

  1. 解析 Schema:Prisma CLI 会读取并解析您的 schema.prisma 文件。
  2. 下载查询引擎 (Query Engine):Prisma 会根据您的操作系统(macOS, Windows, Linux)和数据库类型,下载一个与之对应的、用 Rust 语言编写的二进制可执行文件。这就是 Prisma 的核心——查询引擎
  3. 生成 Prisma Client:Prisma CLI 调用这个查询引擎,根据 schema 生成所有 TypeScript/JavaScript 代码和类型定义,并把它们放入 node_modules/@prisma/client 目录中。

所以,您在代码中 import { PrismaClient } from '@prisma/client' 时,引入的就是这份为您量身定制的代码。

流程二:一次查询的生命周期 (prisma.user.findUnique)

这是理解其底层原理最关键的部分。当您在代码中执行一次查询时,旅程是这样的:

  1. 您的代码层 (TypeScript): 您调用 await prisma.user.findUnique({ where: { id: 1 } })。得益于 prisma generate 生成的类型,这里的 where, id 等都享有完美的自动补全和类型检查。
  2. Prisma Client 层 (Node.js/JavaScript)
    • @prisma/client 中的 findUnique 方法被触发。它不会自己去拼接 SQL 字符串。
    • 相反,它会将您的查询请求(包括模型、条件、要选择的字段等)打包成一个序列化的、基于 JSON 的 GraphQL 风格查询
  1. 查询引擎层 (Rust 二进制文件)
    • Prisma Client 通过一个 Node.js 的子进程或 N-API 调用,将上一步生成的 JSON 查询发送给那个用 Rust 编写的、高性能的查询引擎。
    • 这是 Prisma 与传统 ORM 的最大区别。查询逻辑的核心不在 Node.js 层面,而是在这个编译好的、内存安全且速度极快的 Rust 二进制文件中。
  1. SQL 生成与执行
    • Rust 查询引擎接收到 JSON 请求后,会进行验证,然后生成最优化的 SQL 语句(比如 SELECT "public"."User"."id", ... FROM "public"."User" WHERE "public"."User"."id" = $1)。
    • 引擎自己管理着一个高效的数据库连接池,它会从池中获取一个连接,并向您的 MySQL 数据库执行这条 SQL。
  1. 结果返回
    • 数据库返回查询结果(表格数据)给 Rust 查询引擎。
    • 引擎将这些原始数据打包成一个 JSON 响应,再发送回 Node.js 层的 Prisma Client。
    • Prisma Client 接收到这个 JSON 响应,将其反序列化成一个带有正确 Date, BigInt 等类型的 JavaScript 对象。
  1. 最终结果: 您的 await 表达式完成,您拿到了一个完全类型化的 user 对象。

独特之处

Prisma 相较于其他传统 ORM 框架(如 Sequelize, TypeORM),其独特之处和优点主要源于它在架构理念上的根本不同。

简单来说,Prisma 不是一个传统的 ORM,它是一个基于代码生成的数据库工具集,这个核心差异带来了以下几个杀手级的优势。

1. schema.prisma 作为唯一真实数据源 (Single Source of Truth)
  • Prisma 的做法: 您在一个名为 schema.prisma 的文件中,使用一种简单、直观的 Prisma 模式语言 (PSL) 来定义您的所有数据模型、关系、数据库连接等。这个文件是您数据结构的唯一蓝图和权威来源。它独立于您的业务逻辑代码。
  • 传统 ORM 的做法: 通常,您需要在您的 TypeScript/JavaScript 代码中,通过装饰器 (Decorators)(如 @Entity(), @Column())来定义数据模型。这意味着您的数据模型定义散落在多个 *.entity.ts 文件中,并且与您的编程语言深度耦合。
  • 优点
    • 清晰和集中:所有数据结构都在一个地方,一目了然。
    • 与语言无关schema.prisma 的定义是声明式的,不依赖于 TypeScript 或 JavaScript 的特定语法,更易于理解和跨团队协作。
2. 极致的类型安全 (Unmatched Type Safety via Code Generation)

这是 Prisma 最广为人知的优点。

  • Prisma 的做法: 当您运行 npx prisma generate 命令时,Prisma 会读取您的 schema.prisma 文件,并为您量身定制生成一个高度优化的、完全类型安全的数据库客户端 (Prisma Client)
  • 传统 ORM 的做法: 通常在运行时(Runtime)依赖 TypeScript 的类型和装饰器来工作。虽然也提供类型安全,但存在“漏洞”。
  • 优点
    • 真正的“所见即所得”:Prisma Client 的类型是根据您的 Schema 精确生成的。如果您只查询了用户的 idname 两个字段,那么返回的 TypeScript 对象类型就只包含 idname,不多也不少。
      const user = await prisma.user.findUnique({ where: { id: 1 }, select: { name: true, email: true }, }); // 在这里,user 的类型是 { name: string, email: string },而不是完整的 User 对象!
    • 杜绝运行时错误:在传统 ORM 中,您有时可以从数据库中只加载部分字段,但 TypeScript 类型上它仍然是一个完整的 User 对象。如果您不小心访问了一个未加载的字段,只会在运行时得到 undefined 并可能导致程序崩溃。Prisma 在编译时就杜绝了这种可能性。
    • 无与伦比的自动补全:因为客户端是为您生成的,所以您在编写查询时,VS Code 可以提供精确到每一个字段、每一个操作(where, select, include, gte, contains...)的自动补全提示。
3. 高性能的查询引擎 (High-Performance Query Engine)
  • Prisma 的做法: 所有复杂的查询解析、SQL 生成和数据库连接管理,都由一个用 Rust 语言编写的、预编译的二进制文件——查询引擎 (Query Engine) 来处理。
  • 传统 ORM 的做法: 查询构建和 SQL 生成的逻辑通常是用 JavaScript/TypeScript 编写的,并在 Node.js 进程中运行。
  • 优点
    • 极致性能:Rust 带来的内存安全和接近 C++ 的性能,使得查询引擎在处理复杂查询时非常高效。
    • 优化:查询引擎会为目标数据库(MySQL, PostgreSQL 等)生成高度优化的 SQL 语句。
    • 高效连接管理:引擎内部管理着高效的数据库连接池,减少了开销。
4. 直观的数据库迁移 (Intuitive Database Migrations)
  • Prisma 的做法: 您只需修改 schema.prisma 这个“蓝图”文件。然后运行 npx prisma migrate dev,Prisma 会自动比较蓝图和数据库的差异,并为您生成人类可读的 SQL 迁移文件,然后应用它。这个过程是声明式的。
  • 传统 ORM 的做法: 通常需要您手动编写迁移文件,使用代码(如 queryRunner.addColumn(...))来描述数据库的变更。这个过程是命令式的。
  • 优点
    • 简单且不易出错:您只需要关心最终的数据模型应该是什么样,而不需要关心如何一步步地用 SQL 实现它。
    • 历史清晰:生成的 SQL 文件让您能清楚地看到每次数据库结构发生了什么变化。
5. 卓越的开发体验 (Superior Developer Experience)
  • Prisma Studio:Prisma 内置了一个现代化的、可以直接在浏览器中使用的数据库图形化界面。只需运行 npx prisma studio,您就可以像操作 Excel 一样直观地查看和编辑您的数据,非常方便。
  • 流畅的工作流:从定义 Schema,到生成客户端,再到编写类型安全的查询和执行数据库迁移,整个流程非常顺畅和统一。

总结对比

特性

Prisma

传统 ORMs (如 TypeORM, Sequelize)

核心理念

代码生成,Schema驱动

运行时,装饰器/类定义驱动

模型定义

schema.prisma

文件 (PSL语言)

在 TypeScript/JavaScript 类上使用装饰器

类型安全

极致,编译时保证,可生成部分类型

良好,但依赖开发者自觉,可能存在运行时错误

查询执行

Rust 编写的二进制查询引擎

在 Node.js 进程中用 JS/TS 执行

数据库迁移

声明式 (修改 Schema,自动生成 SQL)

命令式 (手动编写迁移代码)

开发工具

内置 Prisma Studio,顶级自动补全

依赖第三方数据库工具

总而言之,Prisma 以其独特的代码生成架构为代价,换来了无与伦比的类型安全和卓越的开发体验,而传统 ORM 则提供了更多的运行时灵活性和动态性



文章转载自:

http://L7BzyPjp.mpnff.cn
http://gY1lZGxr.mpnff.cn
http://5RKZdcKK.mpnff.cn
http://f6LTtPqE.mpnff.cn
http://egYiIpuE.mpnff.cn
http://kdJzu8zp.mpnff.cn
http://HGjBvS70.mpnff.cn
http://JUvLuEMf.mpnff.cn
http://KBQ6KJYS.mpnff.cn
http://E1AoBUFD.mpnff.cn
http://Bo2XBFO9.mpnff.cn
http://cn8hkbZ0.mpnff.cn
http://2EkP33R8.mpnff.cn
http://cYkr539k.mpnff.cn
http://gCjV8VCi.mpnff.cn
http://jqnavOq8.mpnff.cn
http://0IAnFRVH.mpnff.cn
http://2JQWetzS.mpnff.cn
http://FZsk0hMR.mpnff.cn
http://Hn8SLhAH.mpnff.cn
http://5bzisSgV.mpnff.cn
http://ko1rNxsh.mpnff.cn
http://u2xb5b4z.mpnff.cn
http://To4VfE8H.mpnff.cn
http://rENwR7rI.mpnff.cn
http://JDymx5cp.mpnff.cn
http://iFfbzp5W.mpnff.cn
http://Qx86kbcv.mpnff.cn
http://M1BW9kge.mpnff.cn
http://AfWez1IH.mpnff.cn
http://www.dtcms.com/a/369120.html

相关文章:

  • 分布式事务的Java实践
  • 精准定位性能瓶颈:深入解析 PaddleOCR v3.2 全新 Benchmark 功能
  • The Algorithmic Foundations of Differential Privacy - 3(2)
  • 亚马逊关键词选择:从人工试错到智能闭环的进化之路
  • WIN11控制面板中丢失BitLocker,找回WIN10控制面板中的BitLocker驱动器加密设置
  • TDengine 时间函数 TODAY() 用户手册
  • 架构性能优化三板斧:从10秒响应到毫秒级的演进之路
  • LeetCode_位运算
  • 每日一算:颜色分类
  • 使用自定义固定公网URL地址远程访问公司内网OA办公系统,本地无需公网IP和专线让外网访问
  • pthread_join函数
  • 视觉项目,怎么选主机
  • AI生成内容的版权问题解析与实操指南
  • Oracle软件在主机平台的应用(课程下载)
  • TVS防护静电二极管选型需要注意哪些参数?-ASIM阿赛姆
  • 数据传输优化-异步不阻塞处理增强首屏体验
  • 通信安全员【单选题】考试题库及答案
  • 【开题答辩全过程】以 基于springboot的职业学校教务管理系统设计与实现为例,包含答辩的问题和答案
  • ImmutableMap
  • Oracle 10g → Oracle 19c 升级后问题解决方案(Pro*C 项目)
  • 使用MS-SWIF框架对大模型进行SFT微调
  • 使用PyTorch构建卷积神经网络(CNN)实现CIFAR-10图像分类
  • 非靶向模型中毒攻击和靶向模型中毒攻击
  • 步步高S9:AI重塑学习体验,定义智能教育新范式
  • 与优秀者同行,“复制经验”是成功的最快捷径
  • 2025 IT行业含金量超高的8大证书推荐
  • 《Keil 开发避坑指南:STM32 头文件加载异常与 RTE 配置问题全解决》
  • 基于STM32设计的激光充电控制系统(华为云IOT)_277
  • Kubernetes(四):Service
  • Android studio 既想拍照又想拿到Bitmap