Node.js 原生 SQLite:無需套件的輕量資料存取方案
在以往,如果你想在 Node.js 中使用 SQLite,通常需要安裝 sqlite3 或 better-sqlite3 等第三方套件。從 Node.js 22.5.0 版本開始,Node.js 正式引入了內建的 node:sqlite 模組,讓開發者在「零外部依賴」的情況下也能輕鬆處理結構化資料。
這對於開發 CLI 工具、小型服務、或是在測試環境中模擬資料庫運作非常方便。
快速開始:建立連線
內建的 SQLite 整合在 node:sqlite 模組中。你可以選擇將資料儲存在檔案中,或是直接存在記憶體 (Memory) 中。
const { DatabaseSync } = require('node:sqlite');
// 建立一個存在硬碟的資料庫實例
const db = new DatabaseSync('./my-data.db');
// 或者建立一個僅限記憶體、程式關閉後即消失的資料庫
// const db = new DatabaseSync(':memory:');
console.log('資料庫已連線');
基礎操作:CRUD 實戰
內建的 SQLite API 採用了 同步 (Synchronous) 的設計,這在處理本地嵌入式資料庫時能避免繁瑣的 Promise 管理,且 V8 引擎在執行這類操作時效率極高。
1. 建立資料表 (Execute)
使用 exec() 方法執行不帶參數的 SQL 指令。
db.exec(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
2. 插入資料 (Prepare & Run)
為了防止 SQL 注入 (SQL Injection) 攻擊,我們應使用 prepare() 先建立預處理陳述式,再使用 run() 傳入參數執行。
const insertUser = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)');
// 執行插入
insertUser.run('小林', 'lin@example.com');
insertUser.run('陳小姐', 'chen@example.com');
console.log('資料已成功插入');
3. 查詢資料 (Query)
all():回傳所有匹配的資料列(陣列)。get():回傳第一筆匹配的資料(物件)。
// 查詢全部
const allUsers = db.prepare('SELECT * FROM users').all();
console.log('所有用戶:', allUsers);
// 帶條件查詢
const findUser = db.prepare('SELECT * FROM users WHERE name = ?');
const user = findUser.get('小林');
console.log('找到用戶:', user.email);
交易處理 (Transactions)
在處理多個相關聯的資料庫操作時,交易 (Transaction) 能確保資料的一致性:要麼全部成功,要麼全部失敗。
db.exec('BEGIN TRANSACTION');
try {
const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)');
insert.run('失敗案例', 'fail@example.com');
// 假設這裡發生了商業邏輯錯誤
// throw new Error('模擬錯誤');
db.exec('COMMIT'); // 提交
console.log('交易成功');
} catch (err) {
db.exec('ROLLBACK'); // 復原
console.error('交易失敗,已回滾:', err.message);
}
為什麼選擇原生 node:sqlite?
- 零依賴:不需要額外下載數十 MB 的二進制編譯檔 (node-gyp),部置與打包更快速。
- 高效能:基於 SQLite 原生 C 語言介面直接調用,效能與主流第三方套件相當。
- 穩定性:由 Node.js 官方團隊維護,確保與核心版本的完美兼容。
目前的狀態:
node:sqlite 目前標記為實驗性 (Experimental) 功能。雖然在 Node.js 22 LTS 已經非常穩定且好用,但在生產環境中使用前,請務必確認你的 Node.js 版本符合要求,並留意 API 版本的細微變動。總結
DatabaseSync是操作資料庫的核心類別。- 務必使用
prepare()處理參數化查詢,杜絕安全漏洞。 - 對於需要極致靈活與輕量的伺服器端應用,原生 SQLite 是你的首選。