Lzm

Knex结合mysql详细用法

2025-08-31 16:46:08

安装依赖

Bash 复制代码
npm install knex mysql2

创建db.js,内容如下

Js 复制代码
import knex from "knex";
const config = {
	client: "mysql2",
	connection: {
		host: "127.0.0.1",
		port: 3306,
		user: "root",
		password: "root",
		database: "mydatabase",
		charset: "utf8mb4", // 支持 Emoji
		timezone: "Z", // UTC 时间
		dateStrings: false, // DATE/TIME 转字符串
	},
	pool: {
		min: 2, // 连接池保持的最小连接数
		max: 10, // 连接池允许的最大连接数
		idleTimeoutMillis: 30000, // 空闲连接在被销毁之前能存活的最长时间(毫秒)
		createTimeoutMillis: 3000,// 创建新连接的超时时间(毫秒)
		acquireTimeoutMillis: 30000, // 获取连接的最大等待时间(毫秒)
		propagateCreateError: false, // 是否将创建连接时的错误向外抛出
	},
};
const db = knex(config);
export default db;

基本查询

Js 复制代码
// 查询所有用户
const users = await db('users').select('*');
// 查询单条
const user = await db('users')
  .select('id', 'username', 'email')
  .where('id', 123)
  .first();

select 支持列名数组或多参数
where 会自动使用占位符防注入
first() 取首条并返回对象

动态条件构建

Js 复制代码
const list = await db('orders')
  .select('*')
  .modify(qb => {
    status   && qb.where('status', status);
    minTotal && qb.where('total', '>=', minTotal);
    keyword  && qb.where('note', 'like', `%${keyword}%`);
  });

常见 where 方法
.whereIn(column, [vals])
.whereNot(column, val)
.whereNull(column) / .whereNotNull(column)
.whereBetween(column, [low, high])
.orWhere(...), .andWhere(...)
.whereRaw('?? = ?', ['col', val])

排序与分页

Js 复制代码
const page     = 2;
const pageSize = 10;
const items = await db('products')
  .select('*')
  .orderBy('created_at', 'desc')
  .limit(pageSize)
  .offset((page - 1) * pageSize);

orderBy 支持多字段:.orderBy([{ column: 'a' }, { column: 'b', order: 'asc' }])
limit + offset 实现分页;结合 count() 用于前端总数展示

关联(Join)查询

Js 复制代码
const rows = await db('posts as p')
  .select('p.id', 'p.title', 'u.username')
  .innerJoin('users as u', 'p.author_id', 'u.id')
  .where('p.published', true);

innerJoin、leftJoin、rightJoin 同理
支持多次 join 叠加
取别名时,用 as

聚合与分组

Js 复制代码
const stats = await db('sales')
  .select('product_id')
  .sum('amount as totalSold')
  .count('id as orderCount')
  .groupBy('product_id')
  .having('totalSold', '>', 1000);

count|sum|avg|min|max 都是聚合方法
groupBy + having 过滤聚合结果

写入、更新、删除

Js 复制代码
// 插入
const [newId] = await db('users').insert({
  username: 'alice',
  email:    'alice@example.com'
});

// 批量插入
await db('tags').insert([{ name: 'js' }, { name: 'node' }]);

// 更新
await db('users')
  .where('id', newId)
  .update({ email: 'alice@new.com' });

// 删除
await db('sessions')
  .where('expires_at', '<', new Date())
  .del();

insert 返回主键数组
update、del 返回受影响行数

原生SQL

Js 复制代码
const raw = await db.raw(
  'SELECT ??, COUNT(*) cnt FROM ?? WHERE ?? > ? GROUP BY ??',
  ['category', 'items', 'stock', 0, 'category']
);

事务

Js 复制代码
await db.transaction(async trx => {
  const [orderId] = await trx('orders').insert({ user_id: 1 });
  await trx('order_items').insert([
    { order_id: orderId, sku: 'A1', qty: 2 },
    { order_id: orderId, sku: 'B2', qty: 1 }
  ]);
});

所有操作通过 trx 对象执行
自动回滚/提交

End