一、MySQL 数据库操作
1.1 安装 mysql2 驱动
1.2 创建连接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const mysql = require('mysql2');
const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'your_password', database: 'myapp' });
connection.connect((err) => { if (err) { console.error('数据库连接失败:', err.message); return; } console.log('数据库连接成功'); });
module.exports = connection;
|
1.3 基本查询(回调方式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| const connection = require('./db/mysql');
connection.query('SELECT * FROM users', (err, results, fields) => { if (err) { console.error('查询失败:', err.message); return; } console.log('查询结果:', results); console.log('字段信息:', fields); });
const userId = 1; connection.query( 'SELECT * FROM users WHERE id = ?', [userId], (err, results) => { if (err) throw err; console.log(results); } );
const newUser = { name: '张三', email: 'zhangsan@example.com', age: 25 }; connection.query( 'INSERT INTO users SET ?', newUser, (err, result) => { if (err) throw err; console.log('插入 ID:', result.insertId); } );
connection.query( 'UPDATE users SET age = ? WHERE id = ?', [26, 1], (err, result) => { if (err) throw err; console.log('影响行数:', result.affectedRows); } );
connection.query( 'DELETE FROM users WHERE id = ?', [1], (err, result) => { if (err) throw err; console.log('删除行数:', result.affectedRows); } );
connection.end();
|
1.4 Promise 方式查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| const mysql = require('mysql2/promise');
async function main() { const connection = await mysql.createConnection({ host: 'localhost', user: 'root', password: 'your_password', database: 'myapp' });
try { const [rows] = await connection.execute('SELECT * FROM users'); console.log(rows);
const [result] = await connection.execute( 'INSERT INTO users (name, email, age) VALUES (?, ?, ?)', ['李四', 'lisi@example.com', 30] ); console.log('插入 ID:', result.insertId);
const [updateResult] = await connection.execute( 'UPDATE users SET age = ? WHERE id = ?', [31, 2] ); console.log('更新行数:', updateResult.affectedRows);
const [deleteResult] = await connection.execute( 'DELETE FROM users WHERE id = ?', [2] ); console.log('删除行数:', deleteResult.affectedRows);
} finally { await connection.end(); } }
main().catch(console.error);
|
1.5 连接池
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const mysql = require('mysql2');
const pool = mysql.createPool({ host: 'localhost', user: 'root', password: 'your_password', database: 'myapp', waitForConnections: true, connectionLimit: 10, queueLimit: 0 });
module.exports = pool.promise();
|
使用连接池:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const db = require('./db/pool');
async function getUsers() { const [rows] = await db.execute('SELECT * FROM users'); return rows; }
async function createUser(name, email, age) { const [result] = await db.execute( 'INSERT INTO users (name, email, age) VALUES (?, ?, ?)', [name, email, age] ); return result.insertId; }
module.exports = { getUsers, createUser };
|
1.6 事务处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| const db = require('./db/pool');
async function transferMoney(fromId, toId, amount) { const connection = await db.getConnection();
try { await connection.beginTransaction();
const [fromRows] = await connection.execute( 'SELECT balance FROM accounts WHERE id = ?', [fromId] );
if (fromRows.length === 0) { throw new Error('转出账户不存在'); }
const fromBalance = fromRows[0].balance; if (fromBalance < amount) { throw new Error('余额不足'); }
await connection.execute( 'UPDATE accounts SET balance = balance - ? WHERE id = ?', [amount, fromId] );
await connection.execute( 'UPDATE accounts SET balance = balance + ? WHERE id = ?', [amount, toId] );
await connection.commit(); console.log('转账成功');
} catch (error) { await connection.rollback(); console.error('转账失败:', error.message); throw error; } finally { connection.release(); } }
|
二、MongoDB 数据库操作
2.1 安装 mongodb 驱动
2.2 创建连接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| const { MongoClient } = require('mongodb');
const uri = 'mongodb://localhost:27017'; const client = new MongoClient(uri);
let database;
async function connect() { try { await client.connect(); console.log('MongoDB 连接成功'); database = client.db('myapp'); return database; } catch (error) { console.error('MongoDB 连接失败:', error.message); throw error; } }
function getDb() { return database; }
module.exports = { connect, getDb };
|
2.3 文档 CRUD 操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| const { connect, getDb } = require('./db/mongo');
async function main() { await connect(); const db = getDb(); const users = db.collection('users');
const insertResult = await users.insertOne({ name: '张三', email: 'zhangsan@example.com', age: 25, createdAt: new Date() }); console.log('插入 ID:', insertResult.insertedId);
const insertManyResult = await users.insertMany([ { name: '李四', email: 'lisi@example.com', age: 30 }, { name: '王五', email: 'wangwu@example.com', age: 28 } ]); console.log('插入数量:', insertManyResult.insertedCount);
const allUsers = await users.find({}).toArray(); console.log('所有用户:', allUsers);
const user = await users.findOne({ name: '张三' }); console.log('查询结果:', user);
const youngUsers = await users.find({ age: { $lt: 30 } }).toArray(); console.log('年龄小于30的用户:', youngUsers);
const updateResult = await users.updateOne( { name: '张三' }, { $set: { age: 26 } } ); console.log('更新行数:', updateResult.modifiedCount);
const updateManyResult = await users.updateMany( { age: { $lt: 30 } }, { $set: { status: 'young' } } ); console.log('更新行数:', updateManyResult.modifiedCount);
const deleteResult = await users.deleteOne({ name: '张三' }); console.log('删除行数:', deleteResult.deletedCount);
const deleteManyResult = await users.deleteMany({ status: 'young' }); console.log('删除行数:', deleteManyResult.deletedCount); }
main().catch(console.error);
|
2.4 聚合查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const { connect, getDb } = require('./db/mongo');
async function aggregateDemo() { await connect(); const db = getDb(); const orders = db.collection('orders');
const result = await orders.aggregate([ { $match: { status: 'completed' } }, { $group: { _id: '$userId', total: { $sum: '$amount' } } }, { $sort: { total: -1 } }, { $limit: 10 } ]).toArray();
console.log('用户消费排行:', result); }
aggregateDemo().catch(console.error);
|
三、Redis 缓存操作
3.1 安装 ioredis
3.2 创建连接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const Redis = require('ioredis');
const redis = new Redis({ host: 'localhost', port: 6379, password: '', db: 0 });
redis.on('connect', () => { console.log('Redis 连接成功'); });
redis.on('error', (err) => { console.error('Redis 错误:', err.message); });
module.exports = redis;
|
3.3 字符串操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| const redis = require('./db/redis');
async function stringDemo() { await redis.set('name', '张三'); await redis.set('age', '25'); await redis.set('token', 'abc123', 'EX', 3600);
const name = await redis.get('name'); console.log('name:', name);
await redis.incr('counter'); await redis.incrby('counter', 10);
const ttl = await redis.ttl('token'); console.log('token 剩余时间:', ttl, '秒');
await redis.del('name'); }
stringDemo().catch(console.error);
|
3.4 哈希操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| const redis = require('./db/redis');
async function hashDemo() { await redis.hset('user:1', 'name', '张三'); await redis.hset('user:1', 'email', 'zhangsan@example.com'); await redis.hset('user:1', 'age', 25);
await redis.hmset('user:2', { name: '李四', email: 'lisi@example.com', age: 30 });
const name = await redis.hget('user:1', 'name'); console.log('name:', name);
const user = await redis.hgetall('user:1'); console.log('user:', user);
const exists = await redis.hexists('user:1', 'name'); console.log('name 字段存在:', exists);
await redis.hdel('user:1', 'age');
await redis.hincrby('user:1', 'age', 1); }
hashDemo().catch(console.error);
|
3.5 列表操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| const redis = require('./db/redis');
async function listDemo() { await redis.lpush('queue', 'task1', 'task2', 'task3');
await redis.rpush('queue', 'task4');
const length = await redis.llen('queue'); console.log('队列长度:', length);
const items = await redis.lrange('queue', 0, -1); console.log('队列内容:', items);
const leftItem = await redis.lpop('queue'); console.log('左侧弹出:', leftItem);
const rightItem = await redis.rpop('queue'); console.log('右侧弹出:', rightItem); }
listDemo().catch(console.error);
|
3.6 发布订阅
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const Redis = require('ioredis'); const publisher = new Redis(); const subscriber = new Redis();
subscriber.subscribe('news', 'weather', (err, count) => { if (err) { console.error('订阅失败:', err.message); return; } console.log(`当前订阅了 ${count} 个频道`); });
subscriber.on('message', (channel, message) => { console.log(`收到消息 [${channel}]: ${message}`); });
setTimeout(() => { publisher.publish('news', '今日头条:Node.js 教程更新'); publisher.publish('weather', '今日天气:晴,25℃'); }, 1000);
|
四、ORM 框架
4.1 Sequelize(MySQL ORM)
安装
1
| npm install sequelize mysql2
|
数据库连接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('myapp', 'root', 'your_password', { host: 'localhost', dialect: 'mysql', logging: false, pool: { max: 5, min: 0, acquire: 30000, idle: 10000 } });
async function testConnection() { try { await sequelize.authenticate(); console.log('数据库连接成功'); } catch (error) { console.error('数据库连接失败:', error.message); } }
testConnection();
module.exports = sequelize;
|
定义模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| const { DataTypes } = require('sequelize'); const sequelize = require('../db/sequelize');
const User = sequelize.define('User', { id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: DataTypes.STRING(50), allowNull: false, validate: { notEmpty: true } }, email: { type: DataTypes.STRING(100), allowNull: false, unique: true, validate: { isEmail: true } }, age: { type: DataTypes.INTEGER, defaultValue: 18, validate: { min: 0, max: 120 } }, status: { type: DataTypes.ENUM('active', 'inactive'), defaultValue: 'active' } }, { tableName: 'users', timestamps: true, paranoid: true });
module.exports = User;
|
CRUD 操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| const User = require('./models/User');
async function createUser() { const user = await User.create({ name: '张三', email: 'zhangsan@example.com', age: 25 }); console.log('创建成功:', user.id); }
async function findAllUsers() { const users = await User.findAll({ attributes: ['id', 'name', 'email'], where: { status: 'active' }, order: [['createdAt', 'DESC']], limit: 10 }); console.log(users); }
async function findUserById(id) { const user = await User.findByPk(id); if (!user) { console.log('用户不存在'); return; } console.log(user); }
async function updateUser(id, newData) { const result = await User.update(newData, { where: { id } }); console.log('更新行数:', result[0]); }
async function deleteUser(id) { const result = await User.destroy({ where: { id } }); console.log('删除行数:', result); }
async function forceDeleteUser(id) { const result = await User.destroy({ where: { id }, force: true }); console.log('删除行数:', result); }
|
4.2 Mongoose(MongoDB ODM)
安装
数据库连接
1 2 3 4 5 6 7 8
| const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/myapp') .then(() => console.log('MongoDB 连接成功')) .catch(err => console.error('MongoDB 连接失败:', err.message));
module.exports = mongoose;
|
定义模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({ name: { type: String, required: [true, '姓名不能为空'], trim: true, maxlength: 50 }, email: { type: String, required: true, unique: true, match: [/^\S+@\S+\.\S+$/, '邮箱格式不正确'] }, age: { type: Number, default: 18, min: 0, max: 120 }, role: { type: String, enum: ['user', 'admin'], default: 'user' } }, { timestamps: true, versionKey: false });
userSchema.methods.getDisplayName = function() { return `${this.name} (${this.email})`; };
userSchema.statics.findByEmail = function(email) { return this.findOne({ email }); };
userSchema.pre('save', function(next) { console.log('保存前:', this); next(); });
const User = mongoose.model('User', userSchema);
module.exports = User;
|
CRUD 操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| const User = require('./models/User');
async function createUser() { const user = await User.create({ name: '张三', email: 'zhangsan@example.com', age: 25 }); console.log('创建成功:', user.id); }
async function findAllUsers() { const users = await User.find() .select('name email age') .where('role').equals('user') .sort('-createdAt') .limit(10); console.log(users); }
async function findUserById(id) { const user = await User.findById(id); if (!user) { console.log('用户不存在'); return; } console.log(user); }
async function findByEmail(email) { const user = await User.findByEmail(email); console.log(user); }
async function updateUser(id, newData) { const user = await User.findByIdAndUpdate( id, newData, { new: true, runValidators: true } ); console.log(user); }
async function deleteUser(id) { await User.findByIdAndDelete(id); console.log('删除成功'); }
|
五、实战练习:博客系统 API
5.1 项目结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| blog-api/ ├── config/ │ └── database.js ├── models/ │ ├── User.js │ ├── Post.js │ └── Comment.js ├── controllers/ │ ├── userController.js │ ├── postController.js │ └── commentController.js ├── routes/ │ ├── users.js │ ├── posts.js │ └── comments.js ├── middleware/ │ └── auth.js ├── app.js └── package.json
|
5.2 数据库配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const { Sequelize } = require('sequelize');
const sequelize = new Sequelize( process.env.DB_NAME || 'blog', process.env.DB_USER || 'root', process.env.DB_PASSWORD || '', { host: process.env.DB_HOST || 'localhost', dialect: 'mysql', logging: false } );
module.exports = sequelize;
|
5.3 定义模型关联
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| const { DataTypes } = require('sequelize'); const sequelize = require('../config/database');
const User = sequelize.define('User', { username: { type: DataTypes.STRING(50), allowNull: false, unique: true }, email: { type: DataTypes.STRING(100), allowNull: false, unique: true }, password: { type: DataTypes.STRING(255), allowNull: false } });
module.exports = User;
const { DataTypes } = require('sequelize'); const sequelize = require('../config/database');
const Post = sequelize.define('Post', { title: { type: DataTypes.STRING(200), allowNull: false }, content: { type: DataTypes.TEXT, allowNull: false }, status: { type: DataTypes.ENUM('draft', 'published'), defaultValue: 'draft' } });
module.exports = Post;
const sequelize = require('../config/database'); const User = require('./User'); const Post = require('./Post');
User.hasMany(Post, { foreignKey: 'authorId', as: 'posts' }); Post.belongsTo(User, { foreignKey: 'authorId', as: 'author' });
module.exports = { sequelize, User, Post };
|
💡 小结:掌握数据库操作是后端开发的核心能力。MySQL 适合结构化数据和复杂查询,MongoDB 适合灵活的文档存储,Redis 适合缓存和会话管理。ORM 框架能大幅提升开发效率,但也要注意性能优化和查询优化。