40岁了, 还在写JS
先看参数化查询 ------ 安全、简洁、防注入:
ts
import { Database } from "bun:sqlite";
const db = new Database("app.db");
const userInput = "Alice"; // 恶意输入 '; DROP TABLE users; -- 也会被转义
db.run("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)");
db.run("INSERT INTO users (name) VALUES (?)", [userInput]);
const user = db.query("SELECT * FROM users WHERE name = ?").get(userInput);
console.log(user);
下面 10 个技巧,让你在 Bun 中把 SQLite 用到极致。
1. 参数化查询:防注入唯一正解
永远用 ? 占位符传值,绝不拼接字符串。
ts
const insert = db.prepare("INSERT INTO logs (level, msg) VALUES (?, ?)");
insert.run("INFO", "系统启动");
const search = db.query("SELECT * FROM logs WHERE level = ?");
const errors = search.all("ERROR");
2. 内存+WAL:极速与并发
内存数据库临时用,WAL 模式提升读写并发。
ts
const memDb = new Database(":memory:");
db.exec("PRAGMA journal_mode = WAL");
db.exec("PRAGMA synchronous = NORMAL");
3. 批量事务:每秒五万写入
事务包裹预编译语句,批量插入效率暴增。
ts
const stmt = db.prepare("INSERT INTO sensors (val) VALUES (?)");
const batch = db.transaction((arr) => {
for (const v of arr) stmt.run(v);
});
batch([1, 2, 3, 4, 5]);
4. JSON 支持:像 NoSQL 一样
直接存 JSON,按字段查询,省掉文档数据库。
ts
db.run("CREATE TABLE cfg (key TEXT, val JSON)");
db.run("INSERT INTO cfg VALUES (?, ?)", ["theme", JSON.stringify({ dark: true })]);
const dark = db.query("SELECT json_extract(val, '$.dark') FROM cfg").get();
5. 全文检索:轻量搜索引擎
FTS5 虚拟表,日志搜索毫秒级响应。
ts
db.exec("CREATE VIRTUAL TABLE posts USING fts5(title, body)");
db.exec("INSERT INTO posts VALUES ('Bun 发布', '速度极快')");
const res = db.query("SELECT * FROM posts WHERE posts MATCH '速度'").all();
6. 递归 CTE:树形查询一行
组织架构、菜单树,一条 SQL 搞定层级遍历。
ts
db.exec("CREATE TABLE dept(id INT, name TEXT, pid INT)");
const tree = db.query(`
WITH RECURSIVE t AS (
SELECT id, name, 0 lvl FROM dept WHERE pid IS NULL
UNION ALL
SELECT d.id, d.name, t.lvl + 1 FROM dept d JOIN t ON d.pid = t.id
)
SELECT * FROM t
`).all();
7. 窗口函数:移动平均排名
环比、同比、排名,无需子查询。
ts
db.exec("CREATE TABLE sales(month TEXT, amt INT)");
const avg = db.query(`
SELECT month, amt,
AVG(amt) OVER (ORDER BY month ROWS 1 PRECEDING) as prev_avg
FROM sales
`).all();
8. 生成列:自动计算属性
面积、全名等派生字段,数据库自动维护。
ts
db.exec(`
CREATE TABLE rect(
w REAL,
h REAL,
area REAL GENERATED ALWAYS AS (w * h) STORED
)
`);
db.run("INSERT INTO rect(w, h) VALUES (3, 4)");
const a = db.query("SELECT area FROM rect").get(); // 12
9. 外键级联:数据完整性
开启外键,删除主表自动清理子表。
ts
db.exec("PRAGMA foreign_keys = ON");
db.exec("CREATE TABLE users(id INT PRIMARY KEY)");
db.exec(`
CREATE TABLE orders(
id INT,
uid INT REFERENCES users(id) ON DELETE CASCADE
)
`);
db.run("DELETE FROM users WHERE id = 1"); // 自动删订单
10. 触发器+清理:自动维护与回收
更新时间戳自动更新,定期 VACUUM 释放空间。
ts
db.exec(`
CREATE TRIGGER update_time
AFTER UPDATE ON todos
BEGIN
UPDATE todos SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;
`);
db.exec("DELETE FROM logs WHERE ts < strftime('%s', 'now', '-7 days')");
db.exec("VACUUM");
总结
参数化查询保安全,JSON+全文检索扩能力,窗口+递归解难题,事务+WAL 提性能。Bun 让 SQLite 在边缘设备和桌面应用中都如鱼得水。