Node.js 数据库操作实践
数据库选择
Node.js 支持多种数据库,常见的有:
- MongoDB:NoSQL 文档数据库
- MySQL/PostgreSQL:关系型数据库
- Redis:内存键值数据库
MongoDB 操作
安装和连接
bash
npm install mongodbjavascript
const { MongoClient } = require('mongodb');
const uri = 'mongodb://localhost:27017';
const client = new MongoClient(uri);
async function connect() {
try {
await client.connect();
console.log('连接 MongoDB 成功');
return client.db('mydb');
} catch (err) {
console.error('连接失败:', err);
throw err;
}
}基本 CRUD 操作
javascript
async function crudOperations() {
const db = await connect();
const collection = db.collection('users');
// 创建(Create)
const insertResult = await collection.insertOne({
name: 'John',
email: 'john@example.com',
age: 30
});
console.log('插入文档 ID:', insertResult.insertedId);
// 插入多个文档
const insertManyResult = await collection.insertMany([
{ name: 'Jane', email: 'jane@example.com', age: 25 },
{ name: 'Bob', email: 'bob@example.com', age: 35 }
]);
// 读取(Read)
// 查找单个文档
const user = await collection.findOne({ name: 'John' });
console.log('用户:', user);
// 查找多个文档
const users = await collection.find({ age: { $gte: 30 } }).toArray();
console.log('30岁以上的用户:', users);
// 更新(Update)
const updateResult = await collection.updateOne(
{ name: 'John' },
{ $set: { age: 31 } }
);
console.log('更新文档数:', updateResult.modifiedCount);
// 更新多个文档
const updateManyResult = await collection.updateMany(
{ age: { $lt: 30 } },
{ $set: { status: 'young' } }
);
// 删除(Delete)
const deleteResult = await collection.deleteOne({ name: 'John' });
console.log('删除文档数:', deleteResult.deletedCount);
// 删除多个文档
const deleteManyResult = await collection.deleteMany({ age: { $gt: 40 } });
}查询操作
javascript
async function queryOperations() {
const db = await connect();
const collection = db.collection('users');
// 条件查询
const users = await collection.find({
age: { $gte: 25, $lte: 35 },
email: { $regex: /@example\.com$/ }
}).toArray();
// 排序
const sortedUsers = await collection
.find()
.sort({ age: -1 }) // 降序
.toArray();
// 限制和跳过
const paginatedUsers = await collection
.find()
.skip(10) // 跳过前 10 条
.limit(20) // 限制 20 条
.toArray();
// 投影(选择字段)
const userNames = await collection
.find({}, { projection: { name: 1, email: 1 } })
.toArray();
// 计数
const count = await collection.countDocuments({ age: { $gte: 30 } });
console.log('30岁以上的用户数:', count);
}索引
javascript
async function createIndexes() {
const db = await connect();
const collection = db.collection('users');
// 创建单字段索引
await collection.createIndex({ email: 1 });
// 创建唯一索引
await collection.createIndex({ email: 1 }, { unique: true });
// 创建复合索引
await collection.createIndex({ name: 1, age: -1 });
// 查看索引
const indexes = await collection.indexes();
console.log('索引列表:', indexes);
}Mongoose ODM
Mongoose 是 MongoDB 的对象文档映射(ODM)库。
安装和连接
bash
npm install mongoosejavascript
const mongoose = require('mongoose');
const uri = 'mongodb://localhost:27017/mydb';
async function connect() {
try {
await mongoose.connect(uri);
console.log('Mongoose 连接成功');
} catch (err) {
console.error('连接失败:', err);
}
}定义模型
javascript
const mongoose = require('mongoose');
// 定义 Schema
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
required: true,
unique: true,
lowercase: true
},
age: {
type: Number,
min: 0,
max: 120
},
createdAt: {
type: Date,
default: Date.now
}
});
// 添加实例方法
userSchema.methods.getInfo = function() {
return `${this.name} (${this.email})`;
};
// 添加静态方法
userSchema.statics.findByEmail = function(email) {
return this.findOne({ email });
};
// 创建模型
const User = mongoose.model('User', userSchema);
module.exports = User;使用模型
javascript
// 创建文档
const user = new User({
name: 'John',
email: 'john@example.com',
age: 30
});
await user.save();
// 或者使用 create
const newUser = await User.create({
name: 'Jane',
email: 'jane@example.com',
age: 25
});
// 查询
const users = await User.find({ age: { $gte: 30 } });
const user = await User.findById(userId);
const userByEmail = await User.findByEmail('john@example.com');
// 更新
await User.updateOne({ _id: userId }, { age: 31 });
await User.findByIdAndUpdate(userId, { age: 31 }, { new: true });
// 删除
await User.deleteOne({ _id: userId });
await User.findByIdAndDelete(userId);MySQL 操作
安装和连接
bash
npm install mysql2javascript
const mysql = require('mysql2/promise');
async function connect() {
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'mydb'
});
console.log('连接 MySQL 成功');
return connection;
}基本操作
javascript
async function mysqlOperations() {
const connection = await connect();
try {
// 查询
const [rows] = await connection.execute(
'SELECT * FROM users WHERE age >= ?',
[30]
);
console.log('用户列表:', rows);
// 插入
const [result] = await connection.execute(
'INSERT INTO users (name, email, age) VALUES (?, ?, ?)',
['John', 'john@example.com', 30]
);
console.log('插入 ID:', result.insertId);
// 更新
const [updateResult] = await connection.execute(
'UPDATE users SET age = ? WHERE id = ?',
[31, userId]
);
console.log('影响行数:', updateResult.affectedRows);
// 删除
const [deleteResult] = await connection.execute(
'DELETE FROM users WHERE id = ?',
[userId]
);
} finally {
await connection.end();
}
}连接池
javascript
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'mydb',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
async function usePool() {
const [rows] = await pool.execute('SELECT * FROM users');
return rows;
}Sequelize ORM
Sequelize 是 Node.js 的 ORM 框架,支持多种数据库。
安装和连接
bash
npm install sequelize mysql2javascript
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('mydb', 'root', 'password', {
host: 'localhost',
dialect: 'mysql'
});
async function connect() {
try {
await sequelize.authenticate();
console.log('Sequelize 连接成功');
} catch (err) {
console.error('连接失败:', err);
}
}定义模型
javascript
const { DataTypes } = require('sequelize');
const User = sequelize.define('User', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING,
allowNull: false
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
age: {
type: DataTypes.INTEGER,
validate: {
min: 0,
max: 120
}
}
}, {
tableName: 'users',
timestamps: true
});使用模型
javascript
// 创建
const user = await User.create({
name: 'John',
email: 'john@example.com',
age: 30
});
// 查询
const users = await User.findAll({ where: { age: { [Op.gte]: 30 } } });
const user = await User.findByPk(userId);
// 更新
await User.update({ age: 31 }, { where: { id: userId } });
await user.update({ age: 31 });
// 删除
await User.destroy({ where: { id: userId } });
await user.destroy();Redis 操作
安装和连接
bash
npm install redisjavascript
const redis = require('redis');
const client = redis.createClient({
url: 'redis://localhost:6379'
});
client.on('error', (err) => console.error('Redis 错误:', err));
await client.connect();
console.log('Redis 连接成功');基本操作
javascript
// 字符串操作
await client.set('key', 'value');
const value = await client.get('key');
// 设置过期时间
await client.setEx('key', 3600, 'value'); // 1 小时后过期
// 哈希操作
await client.hSet('user:1', {
name: 'John',
email: 'john@example.com',
age: '30'
});
const user = await client.hGetAll('user:1');
// 列表操作
await client.lPush('list', 'item1', 'item2');
const items = await client.lRange('list', 0, -1);
// 集合操作
await client.sAdd('set', 'member1', 'member2');
const members = await client.sMembers('set');数据库最佳实践
1. 连接管理
javascript
// 使用连接池
const pool = mysql.createPool({
connectionLimit: 10,
// ... 其他配置
});
// 使用单例模式管理连接
class Database {
constructor() {
this.connection = null;
}
async connect() {
if (!this.connection) {
this.connection = await mysql.createConnection(config);
}
return this.connection;
}
}2. 错误处理
javascript
async function safeQuery(query, params) {
try {
const [rows] = await connection.execute(query, params);
return { success: true, data: rows };
} catch (err) {
console.error('查询错误:', err);
return { success: false, error: err.message };
}
}3. 事务处理
javascript
// MongoDB 事务
const session = client.startSession();
try {
await session.withTransaction(async () => {
await collection1.insertOne({ data: 1 }, { session });
await collection2.insertOne({ data: 2 }, { session });
});
} finally {
await session.endSession();
}
// MySQL 事务
await connection.beginTransaction();
try {
await connection.execute('INSERT INTO ...');
await connection.execute('UPDATE ...');
await connection.commit();
} catch (err) {
await connection.rollback();
throw err;
}总结
Node.js 数据库操作要点:
- MongoDB:使用原生驱动或 Mongoose ODM
- MySQL:使用 mysql2 或 Sequelize ORM
- Redis:用于缓存和会话存储
- 连接管理:使用连接池提高性能
- 错误处理:统一的错误处理机制
- 事务处理:确保数据一致性