Prisma 与 Drizzle:NextJS 项目综合指南
在启动一个新的 NextJS 项目时,您将面临的关键决策之一就是选择合适的对象关系映射 (ORM) 工具。TypeScript 生态系统中两个流行的 ORM 工具是 Prisma 和 Drizzle。两者都旨在简化数据库操作,但在方法、理念和功能方面存在显著差异。本文将探讨 Prisma 和 Drizzle 之间的区别,并指导您选择最适合您项目的 ORM 工具。此外,我们还将提供自定义示例,以说明如何在实际场景中使用每个 ORM 工具。
了解 Prisma 和 Drizzle
Prisma 是一款 ORM 框架,旨在解决传统 ORM 框架的诸多问题,例如模型实例臃肿、业务逻辑与存储逻辑混杂以及延迟加载导致的查询不可预测性。它使用 Prisma schema 以声明式的方式定义应用程序模型,并根据该 schema 生成 SQL 迁移。Prisma Client 是一个类型安全的数据库客户端,支持 Node.js 和 TypeScript,提供 CRUD 操作。
另一方面,Drizzle 是一个传统的 SQL 查询构建器,它允许你使用 JavaScript/TypeScript 函数来编写 SQL 查询。它提供了一个查询 API,实现了对 SQL 更高层次的抽象,使你能够读取嵌套关系。Drizzle 的模式定义在 TypeScript 文件中,这些文件随后用于生成和执行针对数据库的 SQL 迁移。
API设计和抽象级别
Drizzle 的理念是“懂 SQL,就懂 Drizzle ORM”。它的 API 与 SQL 完全一致,为精通 SQL 的用户提供了一个熟悉的环境。Prisma Client 则提供了一个更高层次的抽象层,专为应用程序开发人员设计,使用户无需深入了解 SQL 即可轻松完成常见任务。
数据建模
Prisma 模型在 Prisma schema 中定义,而 Drizzle 使用 TypeScript 函数定义表。Prisma 的数据建模 DSL 简洁直观,并拥有强大的 VS Code 扩展,可显著提升开发人员的效率。Drizzle 对 TypeScript 的使用提供了更大的灵活性和代码重用能力。
迁徙
Drizzle 和 Prisma ORM 处理数据库迁移的方式类似,它们都基于模型定义生成 SQL 文件,并提供命令行界面 (CLI) 来执行这些文件。SQL 文件可以在执行前进行修改,从而允许使用这两个系统进行自定义数据库操作。
查询
Drizzle 和 Prisma ORM 都支持自然地构建查询。Drizzle 的查询 API 和 Prisma 的查询方法类似,但 Drizzle 要求使用其类似 SQL 的 API 来进行变更操作,而 Prisma 则提供了一个更流畅的 API 来进行记录的创建、更新或删除。
关系
Prisma ORM 通过虚拟关系字段简化了对外键关联记录的操作,提供流畅的 API、嵌套写入、相关记录筛选以及嵌套数据的类型安全查询。Drizzle 则需要更复杂的 SQL 语句才能实现类似的功能。
过滤
Drizzle 公开了 SQL 方言特定的过滤器和条件运算符,而 Prisma ORM 提供了一组更通用、更直观的运算符,例如contains、startsWith和endsWith。
分页
Drizzle 提供基于限制偏移量的分页,而 Prisma ORM 提供基于限制偏移量和基于游标的分页 API,使其更加灵活。
可观测性
这两个 ORM 框架都支持查询日志记录和 SQL 生成日志记录。Prisma ORM 还具有指标和跟踪等附加功能,可以与外部工具集成以进行性能跟踪。
其他产品和生态系统
Prisma 和 Drizzle 除了各自的 ORM 系统外,还提供其他产品。Prisma Studio 和 Drizzle Studio 允许用户通过图形用户界面 (GUI) 与数据库进行交互。Prisma 还提供 Prisma Accelerate 和 Prisma Pulse 等商业产品,这些产品与 Prisma ORM 集成,可提供全面的数据工具。
Prisma ORM 是一款成熟的 ORM 框架,已被许多元框架和开发平台选为首选的数据层工具。其社区也开发了大量实用工具,以辅助各种工作流程。
数据库支持
Drizzle 和 Prisma 都支持多数据库,Drizzle 通过驱动程序实现这一点,而 Prisma 主要使用内置驱动程序。此外,Prisma 还支持 CockroachDB、Microsoft SQL Server 和 MongoDB 等数据库,而 Drizzle 目前尚不支持这些数据库。
自定义示例:博客平台
我们来看一个博客平台,用户可以在上面创建、更新和删除博客文章。我们将探讨如何使用 Prisma 和 Drizzle 来处理这种情况。
Prisma 示例
// Define models in Prisma schema
model User {
id Int @id @default(autoincrement())
name String?
email String @unique
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
authorId Int?
author User? @relation(fields: [authorId], references: [id])
}
// Create a new post
const newPost = await prisma.post.create({
data: {
title: 'My First Post',
content: 'This is the content of my first post.',
published: true,
authorId: 1,
},
});
// Update a post
const updatedPost = await prisma.post.update({
where: { id: 1 },
data: { title: 'Updated Title' },
});
// Delete a post
const deletedPost = await prisma.post.delete({
where: { id: 1 },
});
毛毛雨示例
import { pgTable, text, boolean, integer, serial } from 'drizzle-orm/pg-core';
// Define tables using TypeScript functions
export const users = pgTable('users', {
id: serial('id').primaryKey(),
name: text('name'),
email: text('email').unique(),
});
export const posts = pgTable('posts', {
id: serial('id').primaryKey(),
title: text('title').notNull(),
content: text('content'),
published: boolean('published'),
authorId: integer('author_id').references(() => users.id),
});
// Create a new post
const newPost = await db.insert(posts).values({
title: 'My First Post',
content: 'This is the content of my first post.',
published: true,
authorId: 1,
});
// Update a post
const updatedPost = await db
.update(posts)
.set({ title: 'Updated Title' })
.where(eq(posts.id, 1))
.returning();
// Delete a post
const deletedPost = await db
.delete(posts)
.where(eq(posts.id, 1))
.returning();
结论
在 NextJS 项目中选择 Prisma 还是 Drizzle,取决于团队对 SQL 的熟悉程度、所需的抽象级别以及具体功能。Prisma 提供了一种更抽象、更便于开发者使用的方法,而 Drizzle 则提供了更接近 SQL 的体验,并具备类型安全功能。两者各有优势,都能有效地用于构建健壮的应用程序。
对于日常使用 SQL 的团队来说,Drizzle 熟悉的类 SQL 语法可能更具吸引力。而对于数据库经验水平参差不齐的团队来说,Prisma 全面且易于学习的方法可能更合适。最终,选择哪种方案应该取决于项目需求、团队专业知识以及您愿意做出的权衡。
那么,你选择的 ORM 工具是什么?
文章来源:https://dev.to/fabrikapp/prisma-vs-drizzle-a-compressive-guide-for-your-nextjs-project-1lfd