摘要:在本教程中,您将学习如何使用内置的 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语句且表具有INTEGERPRIMARYKEY字段时才相关。
例如,以下示例展示了如何将新行插入 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)conn 是 DatabaseSync 类的实例。
其次,定义 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() 方法接受一个具有三个属性 firstName、lastName 和 email 的对象。
create() 方法创建一个预处理语句,使用参数执行预处理语句,并返回一个新插入的联系人。
第三,修改 index.js 以使用 DB.js 和 ContactDB.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()方法以创建一个新的预处理语句,并调用DatabaseSync的run()方法以执行预处理语句。 - 使用
get()方法获取预处理语句返回的第一行。 - 使用
all()方法获取预处理语句的所有行,作为对象数组。