Bun + SQLite 10个实用技巧

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 在边缘设备和桌面应用中都如鱼得水。

相关推荐
Hooray1 小时前
告别低效循环!AI Agent 编排+编程显示器,让前端开发效率实现断代式跃升
前端·人工智能·ai编程
飞天狗1111 小时前
零基础JavaWeb入门——第4课:表单处理 —— 浏览器怎么把数据发给服务器
java·开发语言·前端·后端·servlet
Qres8211 小时前
nodejs安装记录
后端·nodejs
Hooray2 小时前
前端暗黑模式的适配艺术
前端·vue.js·视觉设计
恋猫de小郭2 小时前
解析华为 DevEco Code 和小米 MiMo Code,都基于 OpenCode ,有什么区别?
android·前端·ios
IT_陈寒2 小时前
Vue的响应式让我原地裂开,你们也有这情况吗
前端·人工智能·后端
techdashen2 小时前
用 Rust 真正发出 Ping:FFI 类型、newtype 与 MaybeUninit
开发语言·后端·rust
Boop_wu2 小时前
[Spring Cloud] 快速上手nacos
后端·spring·spring cloud
想吃火锅10052 小时前
【leetcode】20.有效的括号js
linux·javascript·leetcode