1. 关系型数据库(MySQL/PostgreSQL)
以 MySQL 为例,最常用的是 mysql2 或 sequelize ORM:
方式一:直接使用 mysql2(推荐)
javascript
const mysql = require('mysql2/promise'); // 使用 promise 版本
// 1. 创建连接池
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'myapp',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
// 2. 使用 async/await 查询(最现代的方式)
async function getUsers() {
try {
const [rows, fields] = await pool.query('SELECT * FROM users');
return rows;
} catch (error) {
console.error('数据库查询失败:', error);
}
}
// 3. 带参数的查询(防止 SQL 注入)
async function getUserById(id) {
const [rows] = await pool.query('SELECT * FROM users WHERE id = ?', [id]);
return rows[0];
}
// 4. 插入数据
async function createUser(name, email) {
const [result] = await pool.query(
'INSERT INTO users (name, email) VALUES (?, ?)',
[name, email]
);
return result.insertId; // 返回新插入的ID
}
// 使用示例
app.get('/users', async (req, res) => {
const users = await getUsers();
res.json(users);
});
方式二:使用 ORM(Sequelize)- 适合大型项目
javascript
const { Sequelize, DataTypes } = require('sequelize');
// 1. 连接数据库
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql'
});
// 2. 定义模型(类似 Python 的 Django ORM)
const User = sequelize.define('User', {
name: {
type: DataTypes.STRING,
allowNull: false
},
email: {
type: DataTypes.STRING,
unique: true,
validate: {
isEmail: true
}
}
});
// 3. 同步数据库(创建表)
await sequelize.sync();
// 4. 使用 ORM 操作
async function userOperations() {
// 创建用户
const user = await User.create({
name: '张三',
email: 'zhangsan@example.com'
});
// 查询用户
const users = await User.findAll();
const user2 = await User.findByPk(1);
const adults = await User.findAll({
where: { age: { [Op.gte]: 18 } }
});
// 更新
await user.update({ name: '李四' });
// 删除
await user.destroy();
}
2. MongoDB(NoSQL)
MongoDB 是 Node.js 的黄金搭档,常用 mongoose ODM:
javascript
const mongoose = require('mongoose');
// 1. 连接数据库
mongoose.connect('mongodb://localhost:27017/myapp', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// 2. 定义 Schema(类似表结构)
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
age: Number,
address: {
city: String,
street: String
},
tags: [String], // 数组字段
createdAt: { type: Date, default: Date.now }
});
// 3. 创建 Model
const User = mongoose.model('User', userSchema);
// 4. 使用 Model 操作数据库
async function mongoOperations() {
// 创建
const user = new User({
name: '王五',
email: 'wangwu@example.com',
age: 25,
address: { city: '北京', street: '长安街' },
tags: ['程序员', 'Node.js']
});
await user.save();
// 查询
const users = await User.find({ age: { $gt: 18 } });
const user2 = await User.findOne({ email: 'wangwu@example.com' });
// 更新
await User.updateOne(
{ name: '王五' },
{ $set: { age: 26 } }
);
// 删除
await User.deleteOne({ name: '王五' });
// 复杂查询
const programmers = await User.find({
tags: '程序员',
age: { $gte: 20, $lte: 30 }
}).sort({ age: -1 }).limit(10);
}
3. Redis(缓存数据库)
javascript
const Redis = require('ioredis');
// 1. 连接 Redis
const redis = new Redis({
host: 'localhost',
port: 6379,
password: 'optional'
});
// 2. 基本操作
async function redisOperations() {
// 字符串
await redis.set('key', 'value');
const value = await redis.get('key');
// 设置过期时间(5秒)
await redis.setex('session', 5, 'user_data');
// 哈希
await redis.hset('user:1', 'name', '张三');
await redis.hset('user:1', 'age', 30);
const userName = await redis.hget('user:1', 'name');
// 列表
await redis.lpush('logs', 'error1', 'error2');
const latestLog = await redis.lpop('logs');
// 自增(用于计数器)
const views = await redis.incr('page:views');
}
在 Express 中的完整示例
javascript
const express = require('express');
const mysql = require('mysql2/promise');
const app = express();
app.use(express.json());
// 创建数据库连接池
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'myapp'
});
// 获取所有用户
app.get('/api/users', async (req, res) => {
try {
const [rows] = await pool.query('SELECT * FROM users');
res.json(rows);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// 获取单个用户
app.get('/api/users/:id', async (req, res) => {
try {
const [rows] = await pool.query(
'SELECT * FROM users WHERE id = ?',
[req.params.id]
);
if (rows.length === 0) {
return res.status(404).json({ error: '用户不存在' });
}
res.json(rows[0]);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// 创建用户
app.post('/api/users', async (req, res) => {
const { name, email } = req.body;
try {
const [result] = await pool.query(
'INSERT INTO users (name, email) VALUES (?, ?)',
[name, email]
);
res.status(201).json({
id: result.insertId,
name,
email
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// 更新用户
app.put('/api/users/:id', async (req, res) => {
const { name, email } = req.body;
try {
await pool.query(
'UPDATE users SET name = ?, email = ? WHERE id = ?',
[name, email, req.params.id]
);
res.json({ message: '更新成功' });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// 删除用户
app.delete('/api/users/:id', async (req, res) => {
try {
await pool.query('DELETE FROM users WHERE id = ?', [req.params.id]);
res.json({ message: '删除成功' });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
和其他语言的对比
| 操作 | Python (Flask + SQLAlchemy) | PHP (Laravel + Eloquent) | Node.js (Express + Sequelize) |
|---|---|---|---|
| 连接 | create_engine() | DB::connection() | new Sequelize() |
| 查询 | User.query.all() | User::all() | User.findAll() |
| 插入 | db.session.add(user) | User::create($data) | User.create(data) |
| 更新 | user.name = '新名字' | $user->update($data) | user.update({name}) |
| 删除 | db.session.delete(user) | $user->delete() | user.destroy() |
| 事务 | with db.session.begin(): | DB::transaction() | sequelize.transaction() |
关键点总结
- 异步是核心:所有数据库操作都是异步的,要用
async/await - 连接池很重要:不要每次请求都创建新连接
- 防止 SQL 注入:永远使用参数化查询(
?占位符) - ORM vs 原生 SQL:
- 小项目用原生 SQL 更直接
- 大项目用 ORM 更好维护
- 错误处理:数据库操作一定要用 try-catch
新手推荐路线
- 先从
mysql2的原生 SQL 开始,理解数据库操作 - 再用
mongoose体验 MongoDB 的灵活 - 最后用
sequelizeORM 提高效率