Drizzle ORM上手指南:在Next.js中优雅地操作PostgreSQL

前言

在现代 Web 开发中,Next.js 配合 PostgreSQL 数据库已经成为了构建全栈应用的黄金搭档。而 Drizzle ORM 凭借其"无头"、类型安全且接近原生 SQL 的特性,正迅速成为开发者心中的新宠。

本文将带你从零开始,掌握如何在 Next.js 项目中配置 Drizzle,并熟练进行增删改查操作。


🏗️ 第一步:构建数据库连接单例

在开始写业务代码之前,我们需要建立一个数据库连接。在 Next.js 的开发环境中,由于热更新机制,如果每次请求都新建连接,很容易导致连接数耗尽。因此,我们需要使用全局单例模式 来管理 db 实例。

文件路径: src/db/index.ts

typescript 复制代码
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import * as schema from './schema'; // 引入你的表结构定义

// 1. 获取连接字符串
const connectionString = process.env.DATABASE_URL!;

// 2. 创建 postgres 客户端
// 注意:在生产环境建议使用连接池配置,开发环境这样写即可
const client = postgres(connectionString);

// 3. 导出 db 实例
// 这个 `db` 对象就是我们在 API 或组件中用来操作数据库的核心工具
export const db = drizzle(client, { schema });

💡 核心提示: 这个 db 对象封装了连接池和 SQL 构建器。只要在任何文件中 import { db } from '@/db',你就拥有了操作数据库的能力。


📚 第二步:掌握核心增删改查

Drizzle 的语法设计哲学是 "像写 SQL 一样写 TypeScript"。下面我们将通过具体的代码示例,解析最常用的四种操作。

1. 增:插入数据

对应 SQL:INSERT INTO users (name, email) VALUES (...) RETURNING *;

使用 .values() 传入数据对象,配合 .returning() 可以直接拿到插入后的完整数据(包含自增 ID)。

typescript 复制代码
import { db } from '@/db';
import { users } from '@/db/schema';

async function createUser() {
  const newUser = await db.insert(users).values({
    name: "Iron Man",
    email: "ironman@avengers.com"
  }).returning();

  console.log("插入成功:", newUser[0]);
}
2. 删:删除数据

对应 SQL:DELETE FROM users WHERE id = 1;

删除操作必须配合 .where() 使用,否则会导致全表数据被清空(删库跑路警告⚠️)。我们需要引入 eq 函数来构建等值条件。

typescript 复制代码
import { eq } from 'drizzle-orm';

async function deleteUser(userId: number) {
  await db.delete(users).where(eq(users.id, userId));
  console.log("删除成功");
}
3. 改:更新数据

对应 SQL:UPDATE users SET name = 'Captain America' WHERE id = 1;

使用 .set() 指定要修改的字段,同样需要配合 .where() 定位数据。

typescript 复制代码
import { eq } from 'drizzle-orm';

async function updateUser(userId: number) {
  await db.update(users)
    .set({ name: "Captain America" })
    .where(eq(users.id, userId));
    
  console.log("更新成功");
}
4. 查:查询数据

这是最灵活的部分,Drizzle 提供了链式调用来构建复杂的查询语句。

基础查询:

typescript 复制代码
// SELECT * FROM users;
const allUsers = await db.select().from(users);

条件查询:

引入 eq (等于), gt (大于), like (模糊) 等辅助函数。

typescript 复制代码
import { eq, gt, and, like } from 'drizzle-orm';

// SELECT * FROM users WHERE id = 1;
const user = await db.select().from(users).where(eq(users.id, 1));

// 复杂条件:SELECT * FROM users WHERE age > 18 AND name LIKE '%Stark%';
const adults = await db.select()
  .from(users)
  .where(and(gt(users.age, 18), like(users.name, '%Stark%')));

指定字段查询:

typescript 复制代码
// SELECT name, email FROM users;
const names = await db.select({
  name: users.name,
  email: users.email
}).from(users);

🔗 第三步:进阶关联查询

Drizzle 最强大的地方在于类型安全的关联查询。假设你有 users 表和 posts 表,想要查出用户及其文章,可以使用 .leftJoin()

typescript 复制代码
// SELECT * FROM users LEFT JOIN posts ON users.id = posts.userId;
const result = await db.select()
  .from(users)
  .leftJoin(posts, eq(users.id, posts.userId));

// result 的类型会被自动推断为:
// { users: User, posts: Post | null }[]

🛠️ 第四步:Drizzle Kit 命令行工具

除了代码层面的操作,你还需要掌握 Drizzle 的命令行工具来管理数据库结构。

命令 作用 对应 SQL 概念
npx drizzle-kit generate 扫描 schema.ts,生成迁移文件 生成 CREATE TABLE... 等 SQL 脚本
npx drizzle-kit migrate 执行迁移文件,同步到数据库 执行 SQL 脚本
npx drizzle-kit studio 启动可视化界面 类似 pgAdmin 的轻量版

📌 总结

学习 Drizzle 其实就是掌握以下三件事:

  1. 来源 :如何从 src/db/index.ts 导出 db 实例。
  2. 语法db.select(), db.insert(), db.update(), db.delete() 配合 .where().values()
  3. 工具 :使用 drizzle-kit 同步数据库结构。
相关推荐
MarkHD20 小时前
Stable Diffusion入门第19-20天:保存与分享你的工作流——第一阶段收官,从“能用”到“可复用”
java·开发语言·stable diffusion
云水初20 小时前
【agent篇】RAG 知识库构建避坑指南
开发语言·python·学习·agent·rag
2019一路前行20 小时前
Python 函数、循环语句
开发语言·python
CarIise21 小时前
C语言基础课程笔记:硬件原理、数据类型、结构体与格式化输入输出详解
c语言·开发语言·笔记
leoZ23121 小时前
Vue3 还原一个企业级后台-14-项目总结
开发语言·人工智能·后端·opencv·计算机视觉·数据挖掘·rust
茶本无香21 小时前
通用报表自动化框架:Java调用Shell传参执行PostgreSQL SQL模板
java·sql·postgresql·shell
zlinear数据采集卡21 小时前
数据采集卡从入门到精通(7):流水线型ADC——级级接力,高速与高精的平衡术
开发语言·arm开发·嵌入式硬件·fpga开发·c#
Dr.kangder21 小时前
嵌入式面试总结(二十一)——C语言关键字
c语言·开发语言·面试·职场和发展·架构·虚拟化
W_3260021 小时前
Python-OpenCV:库、环境搭建、图片与摄像头解析
开发语言·图像处理·python·opencv·机器学习
zhy2956321 小时前
在 QAIRT Genie SDK 上部署 Llama 3.2 1B 模型:从环境准备到 C++ 推理
开发语言·c++·llama