Node.js SQLite

摘要:在本教程中,您将学习如何使用内置的 SQLite 模块从 Node.js 应用程序与 SQLite 交互。

Node.js 22.5.0 引入了名为 node:sqlite 的实验性 SQLite 模块。在本教程中,您将学习如何使用内置的 node:sqlite 模块从 SQLite 中的表插入、更新、删除和选择数据。

先决条件

  • 熟悉 JavaScript。
  • 对 Node.js 的基本了解。
  • 熟悉 SQLite(如果不熟悉,请查看此 SQLite 教程)。

创建一个新项目

步骤 1. 打开您的终端并创建一个新目录来存储项目

mkdir sqlite-demoCode language: JavaScript (javascript)

步骤 2. 导航到项目目录

cd sqlite-demoCode language: JavaScript (javascript)

步骤 3. 使用 npm init 命令初始化项目

npm init --yCode language: JavaScript (javascript)

此命令将在项目目录中创建一个 package.json 文件。

步骤 4. 在项目目录中创建一个 index.js 文件。这将是 Node.js 应用程序的入口点。

步骤 5. 更改 package.json 文件以支持 ES6 模块

"type": "module",Code language: JavaScript (javascript)

并在 scripts 部分配置 npm start 命令

"scripts": {
  "start": "node --experimental-sqlite index.js"
},Code language: JavaScript (javascript)

请注意,标志 --experimental-sqlite 是必需的,因为内置的 SQLite 模块仍然处于实验阶段。

步骤 6. 使用 npm start 运行应用程序

npm startCode language: JavaScript (javascript)

它将使用 --experimental-sqlite 标志运行 index.js

打开数据库连接

要打开与 SQLite 数据库文件的连接,您可以使用 DatabaseSync 构造函数

const db = new DatabaseSync(location[, options])Code language: JavaScript (javascript)

DatabaseSync 构造函数接受两个参数

  • location 是一个字符串,指定 SQLite 文件的路径。如果您想使用内存中的数据库,则可以传递 ::memory:: 字符串。
  • options 是一个 JavaScript 对象,用于指定连接选项。它具有一个 open 属性,该属性接受一个布尔值。如果 open 为 true,则数据库将由 DatabaseSync 构造函数打开。但是,如果它为 false,则需要通过调用 DatabaseSync 对象的 open() 方法手动打开数据库。

以下示例展示了如何打开与项目目录中位于 (db.sqlite) 的数据库文件的连接

import { DatabaseSync } from 'node:sqlite';

const db = new DatabaseSync('db.sqlite');Code language: JavaScript (javascript)

它是如何工作的。

首先,从 node:sqlite 模块导入 DatabaseSync

import { DatabaseSync } from 'node:sqlite';Code language: JavaScript (javascript)

其次,创建一个新的 DatabaseSync 对象实例以打开与 db.sqlite 数据库文件的连接

const db = new DatabaseSync('db.sqlite');Code language: JavaScript (javascript)

如果您想显式地打开数据库连接,可以使用 DatabaseSync 构造函数的第二个参数

import { DatabaseSync } from 'node:sqlite';

const db = new DatabaseSync('contacts.db', { open: false });
db.open();Code language: JavaScript (javascript)

关闭数据库连接

要关闭打开的数据库连接,您可以调用 DatabaseSync 对象的 close() 方法

db.close();Code language: JavaScript (javascript)

如果您在数据库未打开的情况下调用 close() 方法,它将抛出异常。

以下是连接到 SQLite 文件并关闭数据库连接的完整代码

import { DatabaseSync } from 'node:sqlite';

// open a database connection
const db = new DatabaseSync('db.sqlite');

// interact with the database
// ..

// close the database
if (db) db.close();Code language: JavaScript (javascript)

创建一个新表

要创建一个新表,可以使用 DatabaseSync 对象的 exec() 方法执行 CREATE TABLE 语句。

请注意,exec() 方法可以执行任何 SQL 语句,而不会返回任何结果。

例如,以下示例展示了如何创建一个名为 contacts 的新表

import { DatabaseSync } from 'node:sqlite';

// open a database connection
const db = new DatabaseSync('contacts.db');

// create a new table
db.exec(`
   create table if not exists contacts (
        id integer primary key, 
        firstName text not null, 
        lastName text not null, 
        email text not null    
   )`);

// close the database
if (db) db.close();Code language: JavaScript (javascript)

contacts 表有四列

  • id 是自动增长的主键。
  • firstName 存储联系人的名字。
  • lastName 存储联系人的姓氏。
  • email 存储联系人的电子邮件。

将一行插入表中

要将一行插入表中,请按照以下步骤操作

首先,通过调用 DatabaseSync 对象的 prepare() 方法创建一个预处理语句

const stmt = db.prepare(sql)Code language: JavaScript (javascript)

prepare() 方法接受一个 SQL 字符串并返回一个类型为 StatementSync 的预处理语句对象。

sql 语句可以是插入、更新或删除语句。通常,它包括定义为问号 (?) 的参数占位符,例如 INSERT INTO tableName(c1, c2) VALUES(?,?)

其次,使用值执行预处理语句

const result = stmt.run(value1, value2, ...)Code language: JavaScript (javascript)

run() 方法执行预处理语句并返回一个具有两个属性的对象

  • changes:返回根据 SQL 语句插入、更新或删除的行数。
  • lastInsertRowid:返回最近插入的 rowid。它仅在 sql 语句是 insert 语句且表具有 INTEGER PRIMARY KEY 字段时才相关。

例如,以下示例展示了如何将新行插入 contacts

import { DatabaseSync } from 'node:sqlite';

// open a database connection
const db = new DatabaseSync('contacts.db');

// create a new table
db.exec(`
   create table if not exists contacts (
        id integer primary key, 
        firstName text not null, 
        lastName text not null, 
        email text not null
   )`
);

// insert a new row
const stmt = db.prepare(
  `INSERT INTO contacts (first_name, last_name, email) 
   VALUES (?, ?, ?)`
);

const { lastInsertRowid } = stmt.run('Jane', 'Doe', '[email protected]');

console.log(`Inserted contact id: ${lastInsertRowid}`);

// close the database
if (db) db.close();Code language: JavaScript (javascript)

它是如何工作的。

首先,创建一个将新行插入 contacts 表的预处理语句

const stmt = db.prepare(
  `INSERT INTO contacts (first_name, last_name, email) 
       VALUES (?, ?, ?)`
);Code language: JavaScript (javascript)

其次,使用名字、姓氏和电子邮件值执行预处理语句

const { lastInsertRowid } = stmt.run('Jane', 'Doe', '[email protected]');Code language: JavaScript (javascript)

请注意,我们使用 对象解构 语法从结果对象中解构 lastInsertRowid 属性。

第三,在控制台中显示插入的 id

console.log(`Inserted contact id: ${lastInsertRowid}`);Code language: JavaScript (javascript)

重新组织模块

步骤 1. 使用以下代码创建一个新的文件 DB.js

import { DatabaseSync } from 'node:sqlite';

export class DB {
  constructor(pathToSQLiteFile) {
    this.conn = new DatabaseSync(pathToSQLiteFile);
    this.#init();
  }

  #init() {
    this.conn.exec(`
        create table if not exists contacts (
            id integer primary key, 
            firstName text not null, 
            lastName text not null, 
            email text not null
    )`);
  }

  close() {
    if (this.conn) this.conn.close();
  }
}Code language: JavaScript (javascript)

DB.js 文件中,定义 DB 类,该类执行以下操作

  • 首先,在构造函数中打开与 SQLite 数据库文件的数据库连接,并调用 init() 方法以创建 contacts 表(如果不存在)。请注意,init() 是一个 私有方法,因此它可以在 DB 类中调用。
  • 其次,在 close() 方法中关闭数据库连接。

步骤 2. 在同一个目录中创建一个 ContactDB.js 文件

export class ContactDB {
  constructor(conn) {
    this.conn = conn;
  }

  create({ firstName, lastName, email }) {
    const stmt = this.conn.prepare(
      `INSERT INTO contacts (first_name, last_name, email) 
       VALUES (?, ?, ?)`
    );
    const { lastInsertRowid } = stmt.run(firstName, lastName, email);
    return { id: lastInsertRowid, firstName, lastName, email };
  }
}Code language: JavaScript (javascript)

它是如何工作的。

首先,在构造函数中初始化 conn

constructor(conn) {
    this.conn = conn;
}Code language: JavaScript (javascript)

connDatabaseSync 类的实例。

其次,定义 create() 方法,该方法将新行插入 contacts

create({ firstName, lastName, email }) {
  const stmt = this.conn.prepare(
    `INSERT INTO contacts (first_name, last_name, email) 
       VALUES (?, ?, ?)`
  );
  const { lastInsertRowid } = stmt.run(firstName, lastName, email);
  return { id: lastInsertRowid, firstName, lastName, email };
}Code language: JavaScript (javascript)

create() 方法接受一个具有三个属性 firstNamelastNameemail 的对象。

create() 方法创建一个预处理语句,使用参数执行预处理语句,并返回一个新插入的联系人。

第三,修改 index.js 以使用 DB.jsContactDB.js 模块

import { DB } from './DB.js';
import { ContactDB } from './ContactDB.js';

// open a database connection
const db = new DB('db.sqlite');

const contactDB = new ContactDB(db.conn);
const contact = contactDB.create({
  firstName: 'Jane',
  lastName: 'Doe',
  email: '[email protected]',
});
console.log(contact);

// close the database
db.close();Code language: JavaScript (javascript)

如果您运行该程序,它应该使用以下信息显示新插入的联系人

{
  id: 1,
  firstName: 'Jane',
  lastName: 'Doe',
  email: '[email protected]'
}Code language: JavaScript (javascript)

从表中读取数据

步骤 1. 向联系人模块添加 findById 方法以按 id 查找联系人

findById(id) {
   const stmt = this.conn.prepare(`SELECT * FROM contacts WHERE id = ?`);
   return stmt.get(id);
}Code language: JavaScript (javascript)

它是如何工作的。

首先,创建一个预处理语句,该语句根据 id 从 contacts 表中选择一行

const stmt = this.conn.prepare(`SELECT * FROM contacts WHERE id = ?`);Code language: JavaScript (javascript)

其次,使用输入 id 执行 get() 方法

return stmt.get(id);Code language: JavaScript (javascript)

步骤 2. 修改 index.js 以使用 findById 方法

import { DB } from './DB.js';
import { ContactDB } from './ContactDB.js';

// open a database connection
const db = new DB('db.sqlite');

const contactDB = new ContactDB(db.conn);
const contact = contactDB.findById(1);
console.log(contact);

// close the database connection
db.close();Code language: JavaScript (javascript)

步骤 3. 运行 index.js 文件

npm startCode language: JavaScript (javascript)

输出

{
  id: 1,
  firstName: 'Jane',
  lastName: 'Doe',
  email: '[email protected]'
}Code language: JavaScript (javascript)

更新数据

步骤 1. 修改 ContactDB.js 模块以添加 update() 方法,该方法更新联系人

update({ id, firstName, lastName, email }) {
  const stmt = this.conn.prepare(
    `UPDATE contacts
       SET firstName = ?, lastName = ?, email = ?
       WHERE id = ?`
  );
  const { changes } = stmt.run(firstName, lastName, email, id);
  return changes;
}Code language: JavaScript (javascript)

它是如何工作的。

首先,创建一个预处理语句,该语句更新由 id 指定的联系人的名字、姓氏和电子邮件

const stmt = this.conn.prepare(
  `UPDATE contacts
       SET firstName = ?, lastName = ?, email = ?
       WHERE id = ?`
);Code language: JavaScript (javascript)

其次,执行 UPDATE 语句并获取更新的行数

const { changes } = stmt.run(firstName, lastName, email, id);Code language: JavaScript (javascript)

第三,返回更新的行数

return changes;Code language: JavaScript (javascript)

步骤 2. 修改 index.js 以使用 update() 方法

import { DB } from './DB.js';
import { ContactDB } from './ContactDB.js';

// open a database connection
const db = new DB('db.sqlite');
const contactDB = new ContactDB(db.conn);

// find the contact with id 1
const contact = contactDB.findById(1);

// update the last name and email
contact.lastName = 'Smith';
contact.email = '[email protected]';

// apply the changes to the database
contactDB.update(contact);

// close the database connection
db.close();Code language: JavaScript (javascript)

它是如何工作的。

首先,找到 id 为 1 的联系人

const contact = contactDB.findById(1);Code language: JavaScript (javascript)

其次,更新姓氏和电子邮件

contact.lastName = 'Smith';
contact.email = '[email protected]';Code language: JavaScript (javascript)

第三,将更改应用于数据库

contactDB.update(contact);Code language: JavaScript (javascript)

从表中删除数据

步骤 1. 向 ContactDB 类添加 delete() 方法

function delete(id) {
  const stmt = this.conn.prepare(`DELETE FROM contacts WHERE id = ?`);
  const { changes } = stmt.run(id);
  return changes;
}Code language: JavaScript (javascript)

它是如何工作的。

首先,创建一个预处理语句,该语句根据 id 从 contacts 表中删除一行

const stmt = this.conn.prepare(`DELETE FROM contacts WHERE id = ?`);Code language: JavaScript (javascript)

其次,使用输入 id 执行 DELETE 语句并获取删除的行数

const { changes } = stmt.run(id);Code language: JavaScript (javascript)

第三,返回删除的行数

return changes;Code language: JavaScript (javascript)

步骤 2. 修改 index.js 文件以使用 ContactDB 类的 delete() 方法

import { DB } from './DB.js';
import { ContactDB } from './ContactDB.js';

// open a database connection
const db = new DB('db.sqlite');

const contactDB = new ContactDB(db.conn);

// delete contact with id 1
contactDB.delete(1);

// close the database connection
db.close();Code language: JavaScript (javascript)

步骤 3. 运行 index.js 以删除 id 为 的联系人

contactDB.delete(1);Code language: JavaScript (javascript)

如果您打开 SQLite 文件,您将看到 contacts 表没有行。

从表中读取所有行

步骤 1. 在 ContactDB 类中定义 findAll() 方法以返回 contacts 表中的所有行

findAll() {
  const stmt = this.conn.prepare(`SELECT * FROM contacts`);
  return stmt.all();
}Code language: JavaScript (javascript)

它是如何工作的。

首先,创建一个预处理语句,该语句返回 contacts 表中的所有行

const stmt = this.conn.prepare(`SELECT * FROM contacts`);Code language: JavaScript (javascript)

其次,调用 all() 方法以获取结果集作为联系人对象的数组

return stmt.all();Code language: JavaScript (javascript)

步骤 2. 修改 index.js 文件以使用 findAll() 方法

import { DB } from './DB.js';
import { ContactDB } from './ContactDB.js';

// open a database connection
const db = new DB('db.sqlite');

const contactDB = new ContactDB(db.conn);

// insert 2 contacts
const contacts = [
  {
    firstName: 'John',
    lastName: 'Doe',
    email: '[email protected]',
  },
  {
    firstName: 'Jane',
    lastName: 'Smith',
    email: '[email protected]',
  },
];

for (const contact of contacts) {
  contactDB.create(contact);
}

// find all contacts
contactDB.findAll().forEach(console.log);

// close the database connection
db.close();Code language: JavaScript (javascript)

它是如何工作的。

首先,将两行插入 contacts

const contacts = [
  {
    firstName: 'John',
    lastName: 'Doe',
    email: '[email protected]',
  },
  {
    firstName: 'Jane',
    lastName: 'Smith',
    email: '[email protected]',
  },
];

for (const contact of contacts) {
  contactDB.create(contact);
}Code language: JavaScript (javascript)

其次,找到所有联系人并在控制台中显示每个联系人

contactDB.findAll().forEach(console.log);Code language: JavaScript (javascript)

步骤 3. 运行 index.js 文件

npm startCode language: JavaScript (javascript)

输出

 [
  {
    id: 2,
    firstName: 'John',
    lastName: 'Doe',
    email: '[email protected]'
  },
  {
    id: 3,
    firstName: 'Jane',
    lastName: 'Smith',
    email: '[email protected]'
  }
]Code language: JavaScript (javascript)

下载项目源代码

下载项目源代码

摘要

  • 创建一个新的 DatabaseSync 类实例以打开与 SQLite 数据库文件的连接。
  • 调用 DatabaseSync 对象的 close() 方法以关闭数据库连接。
  • 调用 DatabaseSync 对象的 prepare() 方法以创建一个新的预处理语句,并调用 DatabaseSyncrun() 方法以执行预处理语句。
  • 使用 get() 方法获取预处理语句返回的第一行。
  • 使用 all() 方法获取预处理语句的所有行,作为对象数组。
本教程是否有帮助?