跳到主要内容

数据库集成

添加将数据库连接到 Express 应用程序的功能只需为应用程序中的数据库加载适当的 Node.js 驱动程序即可。

SQLite​

SQLite 是一种轻量级、嵌入式的关系型数据库管理系统。它的设计目标是提供一个零配置、无服务器、跨平台的数据库解决方案。以下是 SQLite 的一些关键特性和限制:

特性描述
轻量级SQLite 是一个非常小的数据库系统,整个库的源代码不到 500 KB。无需安装或配置,所有操作都在单个文件中完成。
嵌入式SQLite 是一个嵌入式数据库,直接集成到应用程序中,不需要独立的数据库服务器。操作由应用程序中的 SQLite 引擎直接处理。
零配置不需要安装、配置或启动数据库服务,所有操作通过直接读写数据库文件完成。适合小型应用和开发过程中。
事务支持支持完整的事务功能,包括 ACID(原子性、一致性、隔离性、持久性)事务,支持多种隔离级别来控制事务的并发操作。
跨平台可以在几乎所有操作系统上运行,包括 Windows、macOS、Linux、iOS、Android 等。数据库文件是跨平台的。
自包含数据库引擎的所有功能都包含在一个库文件中,无需外部依赖,数据库文件本身即为整个数据库。
只读和只写支持支持只读和只写操作,可以在只读环境中运行,也可以在需要写入的环境中使用,支持并发读操作和适度的并发写操作。
SQL 支持支持大部分标准 SQL 语法,包括复杂的查询、联接、索引、触发器、视图等,支持 SQL 数据定义语言(DDL)、数据操纵语言(DML)和数据控制语言(DCL)的主要功能。
限制描述
并发写操作限制虽然 SQLite 支持多个并发读操作,但写操作的并发支持有限。在高并发写操作场景中,SQLite 可能会成为瓶颈。
不支持存储过程和触发器SQLite 不支持存储过程,但支持触发器。
不支持所有 SQL 标准功能尽管 SQLite 支持大部分标准 SQL 功能,但并不完全符合所有 SQL 标准(例如,不支持完全的外键约束和一些高级 SQL 特性)。

安装与使用​

npm install sqlite3

创建一个 SQLite 数据库文件并进行基本操作的示例代码:

const sqlite3 = require('sqlite3').verbose();

// 创建 SQLite3 数据库连接
const db = new sqlite3.Database('./example.db', err => {
if (err) {
console.error('Database connection error:', err.message);
} else {
console.log('Database connected');
}
});

// 创建表
db.run(
'CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)',
err => {
if (err) {
console.error('Table creation error:', err.message);
} else {
console.log('Table created');
}
},
);

// 插入数据
db.run(
'INSERT INTO users (name, email) VALUES (?, ?)',
['Alice', 'alice@example.com'],
function (err) {
if (err) {
console.error('Insert error:', err.message);
} else {
console.log(`Row inserted with ID ${this.lastID}`);
}
},
);

// 查询数据
db.all('SELECT * FROM users', [], (err, rows) => {
if (err) {
console.error('Query error:', err.message);
} else {
console.log('Rows:', rows);
}
});

// 关闭数据库连接
db.close(err => {
if (err) {
console.error('Close error:', err.message);
} else {
console.log('Database connection closed');
}
});

Typeorm​

版本

0.3.20

在使用 Express.js 搭配 SQLite 时,结合 TypeORM 作为 ORM(对象关系映射)可以极大简化数据库操作。TypeORM 允许你通过 JavaScript 或 TypeScript 来映射 SQLite 数据库表,直接操作对象而不是写原生 SQL 语句,从而提高开发效率。

以下是 Express.js 与 SQLite 数据库结合 TypeORM 的完整示例,涵盖基本的 CRUD 操作。

安装依赖​

npm install typeorm reflect-metadata sqlite3
npm install typescript ts-node @types/node --save-dev
  • typeorm: ORM 工具
  • reflect-metadata: TypeScript 的元数据反射库(TypeORM 依赖)
  • sqlite3: SQLite 数据库驱动
  • typescript 和 ts-node: TypeScript 编译工具

TypeORM 配置​

在项目 src 目录下创建一个 data-source.ts 文件,这是 TypeORM 的配置文件。可以指定数据库的类型、路径等。

data-source.ts
import 'reflect-metadata';
import { DataSource } from 'typeorm';
import { User } from './entity/User';

export const AppDataSource = new DataSource({
type: 'sqlite',
database: 'database.sqlite',
synchronize: true,
logging: false,
entities: [User],
migrations: [],
subscribers: [],
});

synchronize: true 会自动同步数据库结构到实体类中,这在开发阶段是非常有用的,但在生产环境中应设置为 false,以避免数据丢失。

如果你将 logging 设置为 true,可以帮助你在开发过程中看到 TypeORM 执行的 SQL 语句,便于调试。

在 src/entity 创建实体类:

User.ts
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";

@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;

@Column()
name: string;

@Column()
email: string;
}

在 src/app.ts 初始化数据:

app.ts
import 'reflect-metadata';
import express, { Request, Response } from 'express';
import { AppDataSource } from './data-source';

const app = express();
app.use(express.json());

AppDataSource.initialize()
.then(() => {
// 启动服务器
app.listen(1234, () => {
console.log('Server is running on port 1234');
});
})
.catch(error => console.log(error));

CRUD 操作​

通过 AppDataSource.initialize() 来初始化数据库连接,在 then 内实现 CRUD 路由。

import { User } from "./entity/User";

AppDataSource.initialize()
.then(() => {
const userRepository = AppDataSource.getRepository(User);

// 创建用户
app.post("/users", async (req: Request, res: Response, next) => {
try {
const { name, email } = req.body;

console.log(name);

const user = new User();
user.name = name;
user.email = email;

await userRepository.save(user);
res.json(user);
} catch (err) {
next(err);
}
});

// 获取所有用户
app.get("/users", async (req, res) => {
const users = await userRepository.find();
res.json(users);
});

// 根据ID获取单个用户
app.get("/users/:id", async (req, res) => {
const user = await userRepository.findOne({
where: { id: JSON.parse(req.params.id) },
});
if (user) {
res.json(user);
} else {
res.status(404).json({ message: "User not found" });
}
});

// 更新用户
app.put("/users/:id", async (req, res) => {
const user = await userRepository.findOne({
where: { id: JSON.parse(req.params.id) },
});
if (user) {
userRepository.merge(user, req.body);
const result = await userRepository.save(user);
res.json(result);
} else {
res.status(404).json({ message: "User not found" });
}
});

// 删除用户
app.delete("/users/:id", async (req, res) => {
const result = await userRepository.delete(req.params.id);
res.json(result);
});

// 启动服务器
app.listen(1234, () => {
console.log("Server is running on port 1234");
});
})
.catch((error) => console.log(error));

Sequelize​

版本

6.37.3

使用 Sequelize 作为 ORM(对象关系映射)来结合 Express.js 和 SQLite,能够方便地与数据库交互并简化复杂的 SQL 操作。Sequelize 是一个支持多种数据库的 ORM 工具,能通过模型与数据库表进行映射,并提供了丰富的 API 来实现各种数据库操作。

安装依赖​

npm install express sequelize sqlite3
npm install typescript ts-node @types/node @types/express --save-dev
  • express: Web 框架
  • sequelize: ORM 工具
  • sqlite3: SQLite 数据库驱动
  • typescript 和 ts-node: TypeScript 编译工具

Sequelize 配置​

在项目 src 目录下创建一个 database.ts 文件,用于初始化 Sequelize 并连接 SQLite 数据库。

database.ts
import { Sequelize } from 'sequelize';

// 初始化 Sequelize 实例,连接 SQLite 数据库
const sequelize = new Sequelize({
dialect: 'sqlite',
storage: 'database.sqlite', // SQLite 数据库文件的路径
});

export default sequelize;

创建模型​

在 src/models 目录下创建一个 User.ts 文件,定义用户模型。Sequelize 模型类似于数据库中的表,允许我们通过 JavaScript 进行增删改查操作

User.ts
import { DataTypes, Model } from 'sequelize';
import sequelize from '../database';

// 定义 User 模型
class User extends Model {
public id!: number;
public name!: string;
public email!: string;
}

User.init(
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
sequelize,
modelName: 'User',
tableName: 'users',
timestamps: false, // 如果不需要 Sequelize 自动生成 createdAt 和 updatedAt
},
);

export default User;

初始化 Sequelize​

在 src/app.ts 文件中初始化 Sequelize 并创建基本的路由以执行 CRUD 操作。

app.ts
import express, { Request, Response } from 'express';
import sequelize from './database';
import User from './models/User';

const app = express();
app.use(express.json());

// 连接数据库并同步模型
sequelize.sync().then(() => {
console.log('Database synced successfully');
});

// 获取所有用户
app.get('/users', async (req: Request, res: Response) => {
const users = await User.findAll();
res.json(users);
});

// 创建新用户
app.post('/users', async (req: Request, res: Response) => {
const { name, email } = req.body;
const user = await User.create({ name, email });
res.json(user);
});

// 根据ID获取单个用户
app.get('/users/:id', async (req: Request, res: Response) => {
const user = await User.findByPk(req.params.id);
if (user) {
res.json(user);
} else {
res.status(404).json({ message: 'User not found' });
}
});

// 更新用户
app.put('/users/:id', async (req: Request, res: Response) => {
const user = await User.findByPk(req.params.id);
if (user) {
user.name = req.body.name;
user.email = req.body.email;
await user.save();
res.json(user);
} else {
res.status(404).json({ message: 'User not found' });
}
});

// 删除用户
app.delete('/users/:id', async (req: Request, res: Response) => {
const result = await User.destroy({ where: { id: req.params.id } });
res.json(result);
});

// 启动服务器
app.listen(1234, () => {
console.log('Server is running on port 1234');
});

Mysql​

MongoDB​