Node.js 24 引入了对 SQLite 的原生支持,通过内置模块 node:sqlite,我们不再需要依赖第三方库(如 better-sqlite3 或 sqlite3)即可高效操作 SQLite 数据库。该模块提供了同步 API,适用于脚本、工具或轻量级服务。
1. 准备工作
确保你使用的是 Node.js v24+(推荐 v24.7.0 或更高):
node -v
# v24.7.0
2. 基本 API 简介
DatabaseSync:代表一个 SQLite 数据库连接(同步)。database.prepare(sql):编译 SQL 语句为预处理语句。statement.run(...):执行 INSERT/UPDATE/DELETE,返回变更信息。statement.get(...):查询单行结果。statement.all(...):查询所有结果。
所有操作均为 同步,适合 CLI 工具、测试脚本、小型应用。
3. 示例:用户 CRUD 操作
我们将实现一个内存数据库,包含 users 表,支持增删改查。
3.1 创建数据库与表
// user-crud.mjs
import { DatabaseSync } from 'node:sqlite';
// 使用内存数据库(也可替换为 'users.db')
const db = new DatabaseSync(':memory:');
// 创建 users 表
db.exec(`
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
) STRICT
`);
STRICT表示启用 SQLite 的严格表模式,增强类型安全。
3.2 创建用户(Create)
const insertUser = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)');
function createUser(name, email) {
const result = insertUser.run(name, email);
return { id: result.lastInsertRowid, name, email };
}
run()返回包含lastInsertRowid和changes的对象。
3.3 查询用户(Read)
const findUserById = db.prepare('SELECT * FROM users WHERE id = ?');
const findAllUsers = db.prepare('SELECT * FROM users');
function getUserById(id) {
return findUserById.get(id) || null;
}
function listAllUsers() {
return findAllUsers.all();
}
get():返回第一条记录(对象)或undefined。all():返回所有记录(数组)。
3.4 更新用户(Update)
const updateUserStmt = db.prepare('UPDATE users SET name = ?, email = ? WHERE id = ?');
function updateUser(id, name, email) {
const result = updateUserStmt.run(name, email, id);
return result.changes > 0; // 返回是否成功更新
}
3.5 删除用户(Delete)
const deleteUserStmt = db.prepare('DELETE FROM users WHERE id = ?');
function deleteUser(id) {
const result = deleteUserStmt.run(id);
return result.changes > 0;
}
4. 完整运行示例
// user-crud.mjs
import { DatabaseSync } from 'node:sqlite';
const db = new DatabaseSync(':memory:');
db.exec(`
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
) STRICT
`);
// Prepare statements
const insertUser = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)');
const findUserById = db.prepare('SELECT * FROM users WHERE id = ?');
const findAllUsers = db.prepare('SELECT * FROM users');
const updateUserStmt = db.prepare('UPDATE users SET name = ?, email = ? WHERE id = ?');
const deleteUserStmt = db.prepare('DELETE FROM users WHERE id = ?');
// CRUD functions
function createUser(name, email) {
const result = insertUser.run(name, email);
return { id: result.lastInsertRowid, name, email };
}
function getUserById(id) {
return findUserById.get(id) || null;
}
function listAllUsers() {
return findAllUsers.all();
}
function updateUser(id, name, email) {
const result = updateUserStmt.run(name, email, id);
return result.changes > 0;
}
function deleteUser(id) {
const result = deleteUserStmt.run(id);
return result.changes > 0;
}
// 示例使用
const user1 = createUser('Alice', 'alice@example.com');
console.log('Created:', user1);
const user2 = createUser('Bob', 'bob@example.com');
console.log('Created:', user2);
console.log('All users:', listAllUsers());
updateUser(user1.id, 'Alice Cooper', 'alice.cooper@example.com');
console.log('Updated Alice:', getUserById(user1.id));
deleteUser(user2.id);
console.log('Bob deleted, remaining users:', listAllUsers());
// 关闭数据库(可选,内存数据库退出即销毁)
db.close();
运行:
node user-crud.mjs
输出示例:
Created: { id: 1n, name: 'Alice', email: 'alice@example.com' }
Created: { id: 2n, name: 'Bob', email: 'bob@example.com' }
All users: [
{ id: 1n, name: 'Alice', email: 'alice@example.com' },
{ id: 2n, name: 'Bob', email: 'bob@example.com' }
]
Updated Alice: { id: 1n, name: 'Alice Cooper', email: 'alice.cooper@example.com' }
Bob deleted, remaining users: [
{ id: 1n, name: 'Alice Cooper', email: 'alice.cooper@example.com' }
]
注意:
id是BigInt(后缀n),因为 SQLite 的ROWID可能超过 JS Number 安全范围。可通过readBigInts: false选项改为 number。
5. 高级提示
5.1 使用命名参数(更清晰)
const stmt = db.prepare('SELECT * FROM users WHERE email = :email');
const user = stmt.get({ email: 'alice@example.com' });
5.2 自动关闭(使用 using 语句,Node.js 21+)
// 需开启 --harmony-explicit-resource-management
using db = new DatabaseSync(':memory:');
// 自动调用 db[Symbol.dispose]()
5.3 文件数据库 vs 内存数据库
':memory:':临时数据库,进程结束即销毁。'./app.db':持久化到文件。
6. 总结
Node.js 24 的 node:sqlite 模块提供了:
✅ 零依赖
✅ 同步 API,简单直接
✅ 支持预处理语句(防 SQL 注入)
✅ 内置事务、备份、扩展支持
非常适合:
-
脚本工具
-
本地应用
-
测试数据库
-
小型 Web 服务(配合 Worker Threads)