Nodejs中有没有一个支持sqlite3同步的库
Nodejs中有没有一个支持sqlite3同步的库
3 回复
Node.js 中有没有一个支持 SQLite3 同步的库?
在 Node.js 生态系统中,大多数数据库操作都是异步的,以避免阻塞主线程。SQLite3 在 Node.js 中通常也是通过异步方式来操作的,但有时我们可能需要使用同步的方式来处理数据库操作。虽然直接的同步库并不多见,但可以通过一些技巧来实现类似的效果。
1. 使用 sqlite3
模块的同步版本
虽然 sqlite3
模块本身主要提供异步接口,但我们可以通过封装异步调用为同步调用来实现这一点。例如:
const sqlite3 = require('sqlite3').verbose();
// 打开数据库文件
const db = new sqlite3.Database(':memory:', (err) => {
if (err) {
console.error(err.message);
}
console.log('Connected to the in-memory SQlite database.');
});
// 封装异步方法为同步方法
function runSync(query, params = []) {
return new Promise((resolve, reject) => {
db.run(query, params, function (err) {
if (err) {
reject(err);
} else {
resolve(this);
}
});
}).then(() => {
return new Promise((resolve) => setTimeout(resolve, 0));
});
}
async function example() {
try {
await runSync("CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)");
await runSync("INSERT INTO test (name) VALUES (?)", ['Alice']);
const rows = await new Promise((resolve) => {
db.all("SELECT * FROM test", [], (err, rows) => {
if (err) {
throw err;
}
resolve(rows);
});
});
console.log(rows);
} catch (error) {
console.error(error);
} finally {
db.close();
}
}
example();
2. 使用 better-sqlite3
库
另一种选择是使用 better-sqlite3
库,它提供了更简洁的 API 并且支持同步操作:
const Database = require('better-sqlite3');
const db = new Database(':memory:');
db.exec(`
CREATE TABLE test (
id INTEGER PRIMARY KEY,
name TEXT
);
`);
db.prepare("INSERT INTO test (name) VALUES (?)").run('Bob');
const rows = db.prepare("SELECT * FROM test").all();
console.log(rows);
db.close();
总结
虽然 sqlite3
模块本身主要是异步的,但你可以通过封装异步方法或者使用 better-sqlite3
这样的库来实现同步操作。这允许你在 Node.js 中以更简单的方式管理 SQLite 数据库。
好像没有,得自己写
在 Node.js 中,sqlite3
库本身是异步的,没有内置的同步版本。不过,你可以通过一些技巧来实现同步操作,例如使用 async/await
结合 Promise 封装同步操作。但是需要注意的是,这种方法本质上仍然是异步的,只是语法上看起来像是同步的。
示例代码
首先,你需要安装 sqlite3
库:
npm install sqlite3
然后你可以创建一个简单的数据库操作类,并封装同步方法:
const sqlite3 = require('sqlite3').verbose();
class Database {
constructor(path) {
this.db = new sqlite3.Database(path);
}
close() {
return new Promise((resolve, reject) => {
this.db.close(err => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
}
run(sql, params = []) {
return new Promise((resolve, reject) => {
this.db.run(sql, params, function(err) {
if (err) {
reject(err);
} else {
resolve(this.lastID);
}
});
});
}
get(sql, params = []) {
return new Promise((resolve, reject) => {
this.db.get(sql, params, (err, row) => {
if (err) {
reject(err);
} else {
resolve(row);
}
});
});
}
all(sql, params = []) {
return new Promise((resolve, reject) => {
this.db.all(sql, params, (err, rows) => {
if (err) {
reject(err);
} else {
resolve(rows);
}
});
});
}
}
// 使用示例
(async () => {
const db = new Database(':memory:');
await db.run('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)');
await db.run('INSERT INTO users (name) VALUES (?)', ['Alice']);
await db.run('INSERT INTO users (name) VALUES (?)', ['Bob']);
const result = await db.get('SELECT * FROM users WHERE id = ?', [1]);
console.log(result); // { id: 1, name: 'Alice' }
await db.close();
})();
解释
- 封装数据库操作:我们创建了一个
Database
类来封装常见的数据库操作(如run
,get
,all
)。 - 使用 Promise:每个方法都返回一个 Promise,这样可以使用
async/await
来简化代码,使其看起来像是同步的。 - 异步操作:尽管使用了
async/await
,但这些方法本质上仍然是异步的。
注意事项
虽然这种封装方式可以使代码看起来更简洁,但仍然需要处理异步错误,例如使用 try/catch
块来捕获可能发生的异常。