摘要:在本教程中,您将学习如何使用内置的 SQLite 模块从 Node.js 应用程序与 SQLite 交互。
Node.js 22.5.0 引入了名为 node:sqlite
的实验性 SQLite 模块。在本教程中,您将学习如何使用内置的 node:sqlite
模块从 SQLite 中的表插入、更新、删除和选择数据。
先决条件
- 熟悉 JavaScript。
- 对 Node.js 的基本了解。
- 熟悉 SQLite(如果不熟悉,请查看此 SQLite 教程)。
创建一个新项目
步骤 1. 打开您的终端并创建一个新目录来存储项目
mkdir sqlite-demo
Code language: JavaScript (javascript)
步骤 2. 导航到项目目录
cd sqlite-demo
Code language: JavaScript (javascript)
步骤 3. 使用 npm init
命令初始化项目
npm init --y
Code 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 start
Code 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)
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 start
Code 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 start
Code 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()
方法获取预处理语句的所有行,作为对象数组。