Node.js 24 原生 SQLite 支持

简介: Node.js 24 原生支持 SQLite(`node:sqlite`),无需第三方库即可高效操作数据库。提供同步 API,含 `DatabaseSync`、预编译语句及完整 CRUD 方法,适用于脚本、工具和轻量服务,零依赖、安全简洁。(239字)

Node.js 24 引入了对 SQLite 的原生支持,通过内置模块 node:sqlite,我们不再需要依赖第三方库(如 better-sqlite3sqlite3)即可高效操作 SQLite 数据库。该模块提供了同步 API,适用于脚本、工具或轻量级服务。

image.png


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() 返回包含 lastInsertRowidchanges 的对象。


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' }
]

注意:idBigInt(后缀 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)

相关文章
|
JSON JavaScript API
Node.js(nodejs)对本地JSON文件进行增、删、改、查操作(轻车熟路)
Node.js(nodejs)对本地JSON文件进行增、删、改、查操作(轻车熟路)
|
5月前
|
前端开发 JavaScript API
什么是 Headless UI?
什么是 Headless UI?
609 115
|
2月前
|
人工智能 安全 Go
使用MCP官方 Go SDK实现自己的MCP server
MCP(Model Context Protocol)是Anthropic推出的标准化协议,让AI安全调用外部工具。本文带你用官方Go SDK从零实现MCP服务器,支持“获取当前时间”和“读取本地文件”两个工具,并在VS Code中快速测试调用。(239字)
453 1
|
2月前
|
Java 应用服务中间件 开发者
Spring Boot 4.0官宣: 弃用 Undertow:Tomcat笑麻了
Spring Boot 4.0.0 M2 正式移除 Undertow 内嵌支持,主因是其未适配 Servlet 6.1 规范,而 Spring Boot 4 强制依赖该规范。本文解析技术动因、迁移影响及平滑过渡方案(推荐切回 Tomcat 或改用 Jetty),助力开发者顺利升级。(239字)
761 1
Spring Boot 4.0官宣: 弃用 Undertow:Tomcat笑麻了
|
2月前
|
安全 Java API
Spring Boot 4 升级实战:从3.x到4.0的分步升级保姆级指南
Spring Boot 4.0于2025年11月发布,基于Spring Framework 7.0,实现模块化(47个轻量自动配置)、JSpecify空安全校验、原生API版本控制等重大升级。镜像减19%、启动快33%,迁移平滑,3.5.x支持至2026年11月。(239字)
3581 1