Express中使用MySQL数据库的完整示例
以下是一个在Express中使用MySQL数据库的完整示例,包含用户管理功能(增删改查),采用模块化结构设计:
项目结构
express-mysql-example/
├── app/
│ ├── config/
│ │ ├── database.js # 数据库连接配置
│ │ └── env.js # 环境变量加载
│ ├── controllers/
│ │ └── userController.js # 用户控制器
│ ├── models/
│ │ └── User.js # 用户模型
│ ├── routes/
│ │ └── userRoutes.js # 用户路由
│ └── app.js # Express应用
├── public/ # 静态资源
├── database/
│ ├── migrations/ # 数据库迁移文件
│ └── seeds/ # 数据种子文件
├── .env # 环境变量
├── package.json # 依赖管理
└── server.js # 服务器启动文件
步骤1:初始化项目
mkdir express-mysql-example && cd express-mysql-example
npm init -y
npm install express mysql2 sequelize dotenv cors
npm install --save-dev nodemon
步骤2:配置环境变量(.env)
# 数据库配置
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=your_password
DB_NAME=express_mysql_example
DB_PORT=3306# 服务器配置
PORT=3000
NODE_ENV=development
步骤3:数据库配置(app/config/database.js)
const { Sequelize } = require('sequelize');
const env = require('./env');const sequelize = new Sequelize(env.DB_NAME,env.DB_USER,env.DB_PASSWORD,{host: env.DB_HOST,port: env.DB_PORT,dialect: 'mysql',logging: env.NODE_ENV === 'development' ? console.log : false,}
);// 测试连接
async function testConnection() {try {await sequelize.authenticate();console.log('数据库连接成功');} catch (error) {console.error('数据库连接失败:', error);process.exit(1);}
}testConnection();module.exports = sequelize;
步骤4:定义用户模型(app/models/User.js)
const { DataTypes } = require('sequelize');
const sequelize = require('../config/database');const User = sequelize.define('User', {id: {type: DataTypes.INTEGER,primaryKey: true,autoIncrement: true,},username: {type: DataTypes.STRING(50),allowNull: false,unique: true,},email: {type: DataTypes.STRING(100),allowNull: false,unique: true,validate: {isEmail: true,},},password: {type: DataTypes.STRING(255),allowNull: false,},role: {type: DataTypes.ENUM('user', 'admin'),defaultValue: 'user',},
});module.exports = User;
步骤5:创建用户控制器(app/controllers/userController.js)
const User = require('../models/User');// 创建用户
exports.createUser = async (req, res) => {try {const { username, email, password, role } = req.body;const user = await User.create({ username, email, password, role });res.status(201).json(user);} catch (error) {res.status(400).json({ error: error.message });}
};// 获取所有用户
exports.getAllUsers = async (req, res) => {try {const users = await User.findAll();res.json(users);} catch (error) {res.status(500).json({ error: '服务器错误' });}
};// 获取单个用户
exports.getUserById = async (req, res) => {try {const user = await User.findByPk(req.params.id);if (!user) {return res.status(404).json({ error: '用户不存在' });}res.json(user);} catch (error) {res.status(500).json({ error: '服务器错误' });}
};// 更新用户
exports.updateUser = async (req, res) => {try {const [updated] = await User.update(req.body, {where: { id: req.params.id },});if (!updated) {return res.status(404).json({ error: '用户不存在' });}const updatedUser = await User.findByPk(req.params.id);res.json(updatedUser);} catch (error) {res.status(400).json({ error: error.message });}
};// 删除用户
exports.deleteUser = async (req, res) => {try {const deleted = await User.destroy({where: { id: req.params.id },});if (!deleted) {return res.status(404).json({ error: '用户不存在' });}res.status(204).send();} catch (error) {res.status(500).json({ error: '服务器错误' });}
};
步骤6:配置路由(app/routes/userRoutes.js)
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');// 用户路由
router.post('/users', userController.createUser);
router.get('/users', userController.getAllUsers);
router.get('/users/:id', userController.getUserById);
router.put('/users/:id', userController.updateUser);
router.delete('/users/:id', userController.deleteUser);module.exports = router;
步骤7:创建Express应用(app/app.js)
const express = require('express');
const cors = require('cors');
const userRoutes = require('./routes/userRoutes');const app = express();// 中间件
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));// 路由
app.use('/api', userRoutes);// 错误处理中间件
app.use((err, req, res, next) => {console.error(err);res.status(500).json({ error: '服务器内部错误' });
});module.exports = app;
步骤8:启动服务器(server.js)
const app = require('./app/app');
const sequelize = require('./app/config/database');
const env = require('./app/config/env');// 同步数据库模型(开发环境)
if (env.NODE_ENV === 'development') {sequelize.sync({ force: false }).then(() => {console.log('数据库模型同步完成');});
}// 启动服务器
const PORT = env.PORT || 3000;
app.listen(PORT, () => {console.log(`服务器运行在端口 ${PORT}`);
});
步骤9:添加package.json脚本
{"scripts": {"start": "node server.js","dev": "nodemon server.js"}
}
步骤10:运行项目
npm run dev
测试API
使用工具如Postman或curl测试以下接口:
-
创建用户
curl -X POST http://localhost:3000/api/users \-H "Content-Type: application/json" \-d '{"username": "john", "email": "john@example.com", "password": "password123"}'
-
获取所有用户
curl http://localhost:3000/api/users
-
获取单个用户
curl http://localhost:3000/api/users/1
-
更新用户
curl -X PUT http://localhost:3000/api/users/1 \-H "Content-Type: application/json" \-d '{"email": "newemail@example.com"}'
-
删除用户
curl -X DELETE http://localhost:3000/api/users/1
数据库迁移(可选)
-
安装Sequelize CLI:
npm install --save-dev sequelize-cli
-
创建迁移文件:
npx sequelize-cli migration:generate --name=create-users
-
编写迁移逻辑:
// database/migrations/xxxxxx-create-users.js module.exports = {up: (queryInterface, Sequelize) => {return queryInterface.createTable('Users', {id: {allowNull: false,autoIncrement: true,primaryKey: true,type: Sequelize.INTEGER},username: {type: Sequelize.STRING,allowNull: false,unique: true},email: {type: Sequelize.STRING,allowNull: false,unique: true},password: {type: Sequelize.STRING,allowNull: false},role: {type: Sequelize.ENUM('user', 'admin'),defaultValue: 'user'},createdAt: {allowNull: false,type: Sequelize.DATE},updatedAt: {allowNull: false,type: Sequelize.DATE}});},down: (queryInterface) => {return queryInterface.dropTable('Users');} };
-
执行迁移:
npx sequelize-cli db:migrate
安全建议
- 密码加密:使用
bcrypt
对密码进行哈希处理 - 输入验证:添加Joi等验证库
- 防止SQL注入:使用ORM的参数化查询
- 环境变量:使用
.env
文件存储敏感信息 - 错误处理:完善错误处理中间件
这个示例展示了Express与MySQL集成的完整流程,包括数据库配置、模型定义、控制器实现和路由配置。根据实际需求,你可以扩展更多功能模块。