数据库集成
本章节介绍 Express.js 与常见数据库的集成方法。
MongoDB + Mongoose
安装配置
npm install mongoose
连接数据库
const mongoose = require('mongoose');
const connectDB = async () => {
try {
await mongoose.connect(process.env.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
});
console.log('MongoDB 连接成功');
} catch (err) {
console.error('MongoDB 连接失败:', err);
process.exit(1);
}
};
connectDB();
定义模型
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
unique: true,
trim: true
},
email: {
type: String,
required: true,
unique: true,
lowercase: true
},
password: {
type: String,
required: true,
minlength: 6
},
role: {
type: String,
enum: ['user', 'admin'],
default: 'user'
}
}, { timestamps: true });
userSchema.pre('save', async function(next) {
if (!this.isModified('password')) return next();
this.password = await bcrypt.hash(this.password, 10);
next();
});
const User = mongoose.model('User', userSchema);
CRUD 操作
const getUsers = async (req, res) => {
const { page = 1, limit = 10 } = req.query;
const users = await User.find()
.select('-password')
.skip((page - 1) * limit)
.limit(limit);
const total = await User.countDocuments();
res.json({ users, total, page, limit });
};
const getUser = async (req, res) => {
const user = await User.findById(req.params.id).select('-password');
if (!user) {
return res.status(404).json({ error: '用户不存在' });
}
res.json(user);
};
const createUser = async (req, res) => {
const user = await User.create(req.body);
res.status(201).json(user);
};
const updateUser = async (req, res) => {
const user = await User.findByIdAndUpdate(
req.params.id,
req.body,
{ new: true, runValidators: true }
).select('-password');
res.json(user);
};
const deleteUser = async (req, res) => {
await User.findByIdAndDelete(req.params.id);
res.json({ message: '删除成功' });
};
MySQL + Sequelize
安装配置
npm install sequelize mysql2
连接数据库
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize(
process.env.DB_NAME,
process.env.DB_USER,
process.env.DB_PASSWORD,
{
host: process.env.DB_HOST,
dialect: 'mysql',
logging: false
}
);
const connectDB = async () => {
try {
await sequelize.authenticate();
console.log('MySQL 连接成功');
await sequelize.sync();
} catch (err) {
console.error('MySQL 连接失败:', err);
}
};
connectDB();
定义模型
const { DataTypes } = require('sequelize');
const User = sequelize.define('User', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
username: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: { isEmail: true }
},
password: {
type: DataTypes.STRING,
allowNull: false
},
role: {
type: DataTypes.ENUM('user', 'admin'),
defaultValue: 'user'
}
}, {
tableName: 'users',
timestamps: true
});
CRUD 操作
const getUsers = async (req, res) => {
const { page = 1, limit = 10 } = req.query;
const offset = (page - 1) * limit;
const { count, rows } = await User.findAndCountAll({
attributes: { exclude: ['password'] },
offset,
limit: parseInt(limit)
});
res.json({ users: rows, total: count, page, limit });
};
const createUser = async (req, res) => {
const user = await User.create(req.body);
res.status(201).json(user);
};
PostgreSQL + Prisma
安装配置
npm install prisma @prisma/client
npx prisma init
Schema 定义
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id @default(autoincrement())
email String @unique
username String @unique
password String
role Role @default(USER)
posts Post[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
authorId Int
author User @relation(fields: [authorId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum Role {
USER
ADMIN
}
CRUD 操作
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
const getUsers = async (req, res) => {
const { page = 1, limit = 10 } = req.query;
const skip = (page - 1) * limit;
const [users, total] = await Promise.all([
prisma.user.findMany({
skip,
take: parseInt(limit),
select: { id: true, email: true, username: true, role: true }
}),
prisma.user.count()
]);
res.json({ users, total, page, limit });
};
const createUser = async (req, res) => {
const user = await prisma.user.create({
data: req.body
});
res.status(201).json(user);
};
const getUserWithPosts = async (req, res) => {
const user = await prisma.user.findUnique({
where: { id: parseInt(req.params.id) },
include: { posts: true }
});
res.json(user);
};
Redis 缓存
npm install redis
const redis = require('redis');
const client = redis.createClient({ url: process.env.REDIS_URL });
client.connect();
const cacheMiddleware = (key, ttl = 3600) => {
return async (req, res, next) => {
const cacheKey = `${key}:${req.originalUrl}`;
const cached = await client.get(cacheKey);
if (cached) {
return res.json(JSON.parse(cached));
}
res.sendResponse = res.json;
res.json = async (data) => {
await client.setEx(cacheKey, ttl, JSON.stringify(data));
res.sendResponse(data);
};
next();
};
};
app.get('/users', cacheMiddleware('users'), getUsers);
数据库连接池
const sequelize = new Sequelize({
database: process.env.DB_NAME,
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
host: process.env.DB_HOST,
dialect: 'mysql',
pool: {
max: 10,
min: 0,
acquire: 30000,
idle: 10000
}
});