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();
})();

解释

  1. 封装数据库操作:我们创建了一个 Database 类来封装常见的数据库操作(如 run, get, all)。
  2. 使用 Promise:每个方法都返回一个 Promise,这样可以使用 async/await 来简化代码,使其看起来像是同步的。
  3. 异步操作:尽管使用了 async/await,但这些方法本质上仍然是异步的。

注意事项

虽然这种封装方式可以使代码看起来更简洁,但仍然需要处理异步错误,例如使用 try/catch 块来捕获可能发生的异常。

回到顶部