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

相关推荐
其实防守也摸鱼5 分钟前
前端应用的离线暂停更新策略:构建稳定可靠的渐进式部署方案
服务器·前端·数据库·学习·ai·命令行·linux系统
太平洋月光13 分钟前
Antv G2中自定义技巧📊
前端·数据可视化
shmily麻瓜小菜鸡24 分钟前
前端“伪防盗链”方案
前端·javascript·vue.js·bootstrap·echarts
Dovis(誓平步青云)25 分钟前
《如何在CentOS 7中添加Plex官方软件源:解决文件磁盘难管理难题》
linux·运维·服务器·后端·生成对抗网络·centos
mayaairi25 分钟前
JS数组完全指南(含十大操作详解)
开发语言·前端·javascript
IT_陈寒1 小时前
Python的线程池把我CPU跑满了,原来少传了个参数
前端·人工智能·后端
喜欢的名字被抢了1 小时前
写-Chrome-扩展时踩过的那些-MV3-的坑
前端·chrome
网安老伯1 小时前
网络安全基础要点知识介绍(非常详细),零基础入门到精通,看这一篇就够了
运维·前端·网络协议·web安全·网络安全·职场和发展
wuqingshun3141591 小时前
springBoot是如何通过main方法启动web项目的?
前端·spring boot·后端
xxwl5851 小时前
HTML 小总结:从骨架到枝叶,系统掌握网页结构
前端·html