Knex.js 入门指南:用 JavaScript 写 SQL

Knex.js 是跨数据库的 SQL 查询构造器:链式 API 构建查询、防注入、支持 PostgreSQL/MySQL/SQLite。本文走完建库、增删改查全流程。

最佳实践
应用接口与数据存储连接插画

Knex 让 SQL 用 JS 链式书写:knex('users').where('age', '>', 18).select('name') 生成参数化查询——既保留 SQL 的表达能力与可控性,又自动防注入、跨数据库方言。它不隐藏 SQL,是"SQL 优先"团队的正确工具。

Knex 的定位

ORM 把数据库抽象成对象,Knex 只把 SQL 抽象成链式调用——表还是表、join 还是 join,你始终知道执行的 SQL 长什么样。换来的:零黑盒、跨方言、参数化防注入。

初始化与建表

npm install knex better-sqlite3
const knex = require('knex')({
  client: 'better-sqlite3',
  connection: { filename: './app.db' },
  useNullAsDefault: true,
});

// 建表
await knex.schema.createTable('users', (table) => {
  table.increments('id');
  table.string('name').notNullable();
  table.string('email').unique().notNullable();
  table.integer('age');
  table.timestamps(true, true);
});

插入数据

const [id] = await knex('users').insert({
  name: '张三', email: 'zhang@example.com', age: 28,
});

// 批量
await knex('users').insert([
  { name: '李四', email: 'li@example.com', age: 32 },
  { name: '王五', email: 'wang@example.com', age: 25 },
]);

参数化是自动的——insert({ name: userInput }) 永远安全,不存在拼接 SQL 注入。

查询数据

// 全量
const users = await knex('users').select('*');

// 条件 + 排序 + 分页
const adults = await knex('users')
  .where('age', '>=', 18)
  .orderBy('age', 'desc')
  .limit(10).offset(20);

// 聚合
const stats = await knex('users')
  .avg('age as avg_age')
  .count('id as total')
  .first();

// join
const rows = await knex('users')
  .join('posts', 'users.id', 'posts.user_id')
  .select('users.name', 'posts.title');

where 支持对象简写({ name: '张三' })、操作符(where('age', '>', 18))、范围(whereBetween)、子查询——SQL 的表达力基本无损映射。

更新与删除

// 更新(务必带 where!)
const affected = await knex('users')
  .where({ id: 1 })
  .update({ age: 29 });

// 删除
await knex('users').where({ id: 1 }).del();

铁律:update/del 不带 where 就是全表操作——代码评审重点盯这一条。

事务

await knex.transaction(async (trx) => {
  await trx('accounts').where({ id: 1 }).decrement('balance', 100);
  await trx('accounts').where({ id: 2 }).increment('balance', 100);
  // 抛错自动回滚,正常结束自动提交
});

用实际查询验证数据访问方案

Knex.js 入门指南的选择最终要落到查询次数、SQL 耗时与连接占用。应用接入观测云 APM 时,先核对 SDK 是否支持实际使用的数据库驱动,不能因为使用了某个 ORM 就假设全部查询自动可见。未覆盖的查询可手动插桩;PostgreSQL 等服务端数据库另配实例采集。SQL 和绑定参数上报前须脱敏,再按相同接口比较 N+1 查询与慢查询的变化。

接入文档:Node.js APM 接入 · PostgreSQL 采集 · 日志采集。

常见问题(FAQ)

Q:Knex 和 ORM 怎么选?

见本系列《Knex 和 Prisma 对比》。一句话:想掌控 SQL 选 Knex,想操作对象选 Prisma/Drizzle。

Q:生产环境数据库迁移怎么管理?

Knex 自带迁移系统:knex migrate:make xxx 生成迁移文件,knex migrate:latest 执行。迁移文件入版本库,CI/CD 流程中自动执行。

Q:Knex 还在维护吗?

维护中且稳定——它是"完成度高"的工具而非"停滞"。TypeScript 支持可用但类型推导有限(Kysely 在类型化方向走得更远)。


参考文档

本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台