@btx4870/postgre-tool
v1.0.0
Published
PostgreSQL 18 chain query helper
Maintainers
Readme
@btx4870/postgre-tool
基于 pg 的链式查询封装,面向 PostgreSQL 18(亦兼容 12+)。值使用 $1,$2...(也可在 query 里写 ? 自动转换),表名/列名走白名单。
要求 Node.js >= 8.0.0。建议实际使用 Node 16+。
安装
npm i @btx4870/postgre-tool初始化
const { createDb } = require('@btx4870/postgre-tool')
const db = createDb({
host: '127.0.0.1',
port: 5432,
user: 'postgres',
password: '123456',
database: 'curtest',
prefix: 'cur_'
})table('user') 查询 "cur_user"。table('user u') 带别名。
查询
const row = await db.table('user').where('id', 1).find()
const list = await db.table('user')
.where('status', 1)
.where('name', 'ilike', '%a%')
.where('id', 'in', ids)
.where('age', 'between', [18, 60])
.where('name|phone', 'like', '%a%')
.order('id DESC')
.page(1, 20)
.select()
await db.table('user').seek('id', lastId).limit(20).select()LIKE 区分大小写,忽略大小写用 ILIKE。
page(页码, 每页条数):OFFSET > 1000 时自动延迟关联。主键不是 id:.page(page, 20, 'uid')。关闭:.page(page, 20, false)。
动态条件缺值会跳过。where('name', null) 生成 IS NULL。值等于操作符单词时写 .where('type', '=', 'like')。
分组 / 聚合 / JOIN / UNION
await db.table('user').count()
await db.table('user').sum('age')
await db.table('user').field('age, COUNT(*) AS c').group('age').having('COUNT(*)', '>=', 1).select()
await db.table('user u')
.field('u.id, o.no')
.leftJoin('order o', 'u.id', 'o.uid')
.where('u.status', 1)
.select()
const a = db.table('user').field('id').where('status', 1)
const b = db.table('user').field('id').where('status', 2)
await a.unionAll(b).order('id ASC').limit(10)写入
单条 insert 使用 RETURNING id,有 id 列时返回主键。
const id = await db.table('user').insert({ name: 'a', age: 18 })
await db.table('user').insert([{ name: 'b', age: 1 }])
await db.table('user').where('id', 1).update({ age: 19 })
await db.table('user').where('id', 1).increment('age', 1)
await db.table('user').where('id', 1).delete()无 WHERE 的 update / delete / increment 会抛错,全表操作用 .force()。
事务 / 锁 / 原始 SQL / 游标
await db.transaction(async (trx) => {
const row = await trx.table('user').where('id', 1).lock().find()
await trx.table('user').where('id', 1).update({ age: row.age + 1 })
})
await db.lock('user', async (d) => {
await d.table('user').where('id', 1).update({ age: 1 })
})
const [rows] = await db.query('SELECT * FROM cur_user WHERE id = ?', [1])
const { rows: rows2 } = await db.query('SELECT * FROM cur_user WHERE id = $1', [1])
await db.table('user').cursor(async (row) => {})行锁 .lock() 必须在 transaction 里。表锁 db.lock 在事务中执行 LOCK TABLE,回调结束提交后自动释放。
窗口函数、WITH RECURSIVE 请直接 db.query,不要硬套链式。
与 mysql-tool 的差异
- 占位符为
$n(链式内部仍写?,执行前转换) - 分页为
LIMIT n OFFSET m - 标识符用
"name" insert依赖RETURNING id- 表锁语法为 PostgreSQL
LOCK TABLE ... IN ... MODE
注意事项
- 列名、表名、JOIN ON 不要用请求参数拼接
whereRaw/query的值必须走参数数组- 空
IN []变为FALSE(查不到行) - 复杂 CTE / 窗口函数用原生 SQL
License
MIT
