使用 Node.js 操作 SQLite的方法
SQLite 是一個(gè)輕量級(jí)的嵌入式關(guān)系型數(shù)據(jù)庫,適合小型項(xiàng)目、原型開發(fā)和本地?cái)?shù)據(jù)存儲(chǔ)。在 Node.js 中使用 SQLite 非常方便,常用的第三方庫是 sqlite3。
一、安裝依賴
首先,在項(xiàng)目中安裝 sqlite3:
npm init -y npm install sqlite3
二、創(chuàng)建并連接數(shù)據(jù)庫
創(chuàng)建一個(gè) db.js 文件:
const sqlite3 = require('sqlite3').verbose();
let db = new sqlite3.Database('./mydb.sqlite', (err) => {
if (err) {
console.error(err.message);
}
console.log('Connected to the mydb SQlite database.');
});這段代碼首先導(dǎo)入了 sqlite3 模塊,并設(shè)置了為 verbose 模式以便于調(diào)試。然后創(chuàng)建了一個(gè)新的 SQLite 數(shù)據(jù)庫連接,如果指定的數(shù)據(jù)庫文件不存在,SQLite 將自動(dòng)創(chuàng)建一個(gè)新的。
三、創(chuàng)建表
db.run(`CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE
)`, function(err) {
if (err) {
console.error(err.message);
}
console.log('Table created');
});這里我們創(chuàng)建了一個(gè)名為 users 的表,包含三個(gè)字段:id、name 和 email。
四、插入/更新/刪除 數(shù)據(jù)
let sql = `INSERT INTO users(name, email) VALUES(?, ?)`;
db.run(sql, ["John Doe", "johndoe@example.com"], function(err) {
if (err) {
console.error(err.message);
}
console.log(`A new row has been inserted with rowid ${this.lastID}`);
});let updateSql = `UPDATE users SET email = ? WHERE name = ?`;
db.run(updateSql, ["newemail@example.com", "John Doe"], function(err) {
if (err) {
console.error(err.message);
}
console.log(`Row(s) updated: ${this.changes}`);
});let deleteSql = `DELETE FROM users WHERE name = ?`;
db.run(deleteSql, ["John Doe"], function(err) {
if (err) {
console.error(err.message);
}
console.log(`Row(s) deleted: ${this.changes}`);
});五、查詢數(shù)據(jù)
查詢數(shù)據(jù)庫中的數(shù)據(jù)可以使用 db.all() 方法:
db.all(`SELECT * FROM users`, [], (err, rows) => {
if (err) {
throw err;
}
rows.forEach((row) => {
console.log(row.id, row.name, row.email);
});
});分頁查詢的基本原理
分頁查詢主要依靠兩個(gè) SQL 關(guān)鍵字:
- LIMIT:限制返回的記錄數(shù)。
- OFFSET:跳過指定數(shù)量的記錄。
-- 第 1 頁(每頁 10 條) SELECT * FROM users LIMIT 10 OFFSET 0; -- 第 2 頁 SELECT * FROM users LIMIT 10 OFFSET 10; -- 第 3 頁 SELECT * FROM users LIMIT 10 OFFSET 20;
基礎(chǔ)實(shí)現(xiàn)方法
使用db.all()方法
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('./mydb.sqlite');
// 分頁參數(shù)
const page = 1;
const pageSize = 10;
const offset = (page - 1) * pageSize;
// 分頁查詢
db.all(
'SELECT * FROM users LIMIT ? OFFSET ?',
[pageSize, offset],
(err, rows) => {
if (err) {
console.error('查詢失敗:', err.message);
} else {
console.log('查詢結(jié)果:', rows);
}
}
);計(jì)算總頁數(shù)
// 查詢總記錄數(shù)
db.get('SELECT COUNT(*) as count FROM users', (err, result) => {
if (err) {
console.error('查詢總記錄數(shù)失敗:', err.message);
} else {
const totalCount = result.count;
const totalPages = Math.ceil(totalCount / pageSize);
console.log(`總記錄數(shù): ${totalCount}, 總頁數(shù): ${totalPages}`);
}
});db.all和db.get是兩個(gè)常用的查詢方法,但它們的功能和用途有明顯區(qū)別:
1. 返回結(jié)果數(shù)量
db.get:- 返回查詢結(jié)果的第一條記錄(單個(gè)對(duì)象)。如果沒有匹配的記錄,則返回
null。
- 返回查詢結(jié)果的第一條記錄(單個(gè)對(duì)象)。如果沒有匹配的記錄,則返回
db.all:- 返回查詢結(jié)果的所有記錄(數(shù)組)。如果沒有匹配的記錄,則返回空數(shù)組
[]。
- 返回查詢結(jié)果的所有記錄(數(shù)組)。如果沒有匹配的記錄,則返回空數(shù)組
2. 回調(diào)參數(shù)
db.get:- 回調(diào)函數(shù)接收
(err, row),其中row是單個(gè)對(duì)象。
- 回調(diào)函數(shù)接收
db.all:- 回調(diào)函數(shù)接收
(err, rows),其中rows是數(shù)組。
- 回調(diào)函數(shù)接收
3.db.get的適用場景
- 查詢唯一記錄(如通過 ID 查詢用戶)。
- 聚合查詢(如
COUNT,SUM,AVG)。 - 只需獲取第一條記錄的場景。
// 查詢單個(gè)用戶
db.get('SELECT * FROM users WHERE id = ?', [1], (err, row) => {
if (err) {
console.error(err);
} else {
console.log(row); // 返回單個(gè)用戶對(duì)象或 null
}
});
// 聚合查詢
db.get('SELECT COUNT(*) as total FROM users', (err, row) => {
console.log(row.total); // 返回總數(shù)
});4.db.all的適用場景
- 查詢多條記錄(如獲取所有用戶)。
- 分頁查詢(結(jié)合
LIMIT和OFFSET)。 - 需要遍歷所有結(jié)果的場景。
// 查詢所有用戶
db.all('SELECT * FROM users', (err, rows) => {
if (err) {
console.error(err);
} else {
console.log(rows); // 返回用戶數(shù)組
rows.forEach(user => {
console.log(user.name);
});
}
});
// 分頁查詢
db.all('SELECT * FROM users LIMIT ? OFFSET ?', [10, 0], (err, rows) => {
// 返回第一頁的 10 條記錄
});db.serialize()是一個(gè)重要的方法,用于控制 SQL 語句的執(zhí)行順序
1. SQLite 的并發(fā)特性
- SQLite 是文件型數(shù)據(jù)庫,同一時(shí)間只能有一個(gè)寫操作。
- 多個(gè)讀操作可以并行,但寫操作會(huì)阻塞所有其他操作。
2.db.serialize()的作用
- 確保同一連接上的 SQL 語句按順序執(zhí)行。
- 防止并發(fā)執(zhí)行導(dǎo)致的數(shù)據(jù)不一致問題。
db.serialize(() => {
// 這里的 SQL 語句會(huì)按順序執(zhí)行
db.run('SQL 語句 1');
db.run('SQL 語句 2');
// ...
});db.serialize(() => {
// 創(chuàng)建表
db.run('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)');
// 插入數(shù)據(jù)
db.run('INSERT INTO users (name) VALUES (?)', ['張三']);
// 查詢數(shù)據(jù)
db.get('SELECT * FROM users WHERE id = 1', (err, row) => {
console.log(row); // 可以確保數(shù)據(jù)已插入
});
});事務(wù)需要順序執(zhí)行
db.serialize(() => {
// 開始事務(wù)
db.run('BEGIN TRANSACTION');
// 執(zhí)行多個(gè)操作
db.run('INSERT INTO users (name) VALUES (?)', ['李四']);
db.run('UPDATE accounts SET balance = balance - 100 WHERE user_id = 1');
// 提交事務(wù)
db.run('COMMIT', (err) => {
if (err) {
db.run('ROLLBACK'); // 出錯(cuò)時(shí)回滾
}
});
});- 事務(wù)中的 SQL 必須按順序執(zhí)行,否則可能導(dǎo)致數(shù)據(jù)不一致。
- 例如,
COMMIT必須在所有操作完成后執(zhí)行。
六、關(guān)閉數(shù)據(jù)庫連接
db.close((err) => {
if (err) {
console.error(err.message);
}
console.log('Close the database connection.');
});到此這篇關(guān)于使用 Node.js 操作 SQLite的文章就介紹到這了,更多相關(guān)node.js操作sqlite內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
npm install安裝離線包的實(shí)現(xiàn)過程
這篇文章主要介紹了npm install安裝離線包的實(shí)現(xiàn)過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-10-10
Node.js實(shí)現(xiàn)下載文件的兩種實(shí)用方式
最近優(yōu)化了幾個(gè)新人寫出的動(dòng)態(tài)表格文件下載接口的性能瓶頸,感覺非常有必要總結(jié)一篇文章作為文檔來拋磚引玉,這篇文章主要給大家介紹了關(guān)于Node.js實(shí)現(xiàn)下載文件的兩種實(shí)用方式,需要的朋友可以參考下2022-09-09
nodejs與瀏覽器中全局對(duì)象區(qū)別點(diǎn)總結(jié)
在本篇文章里小編給大家整理的是一篇關(guān)于nodejs與瀏覽器中全局對(duì)象區(qū)別點(diǎn)總結(jié)內(nèi)容,對(duì)此有需要的朋友們可以學(xué)習(xí)下。2021-12-12
基于NodeJS的前后端分離的思考與實(shí)踐(四)安全問題解決方案
本文就在前后端分離模式的架構(gòu)下,針對(duì)前端在Web開發(fā)中,所遇到的安全問題以及應(yīng)對(duì)措施和注意事項(xiàng),并提出解決方案。2014-09-09
詳解Node.js amqplib 連接 Rabbit MQ最佳實(shí)踐
這篇文章主要介紹了詳解Node.js amqplib 連接 Rabbit MQ最佳實(shí)踐,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01

