MySQL集成 #
一、MySQL简介 #
1.1 什么是MySQL? #
MySQL是最流行的关系型数据库管理系统,具有高性能、高可靠性和易用性。
1.2 特点 #
- 成熟稳定,广泛使用
- 支持事务,ACID特性
- 丰富的索引类型
- 强大的查询优化器
1.3 安装 #
bash
npm install mysql2
二、连接MySQL #
2.1 基本连接 #
javascript
const mysql = require('mysql2');
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'myapp'
});
connection.connect((err) => {
if (err) {
console.error('连接失败:', err);
return;
}
console.log('连接成功');
});
2.2 连接池 #
javascript
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'myapp',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
module.exports = pool;
2.3 配置文件 #
config/database.js:
javascript
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: process.env.DB_HOST || 'localhost',
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || '',
database: process.env.DB_NAME || 'myapp',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
const testConnection = async () => {
try {
const connection = await pool.getConnection();
console.log('数据库连接成功');
connection.release();
} catch (error) {
console.error('数据库连接失败:', error.message);
}
};
module.exports = { pool, testConnection };
三、基本查询 #
3.1 查询数据 #
javascript
const [rows] = await pool.query('SELECT * FROM users');
const [rows] = await pool.query('SELECT * FROM users WHERE id = ?', [id]);
const [rows] = await pool.query('SELECT * FROM users WHERE role = ? AND active = ?', ['admin', true]);
3.2 插入数据 #
javascript
const [result] = await pool.query(
'INSERT INTO users (name, email, password) VALUES (?, ?, ?)',
[name, email, password]
);
console.log('插入ID:', result.insertId);
3.3 更新数据 #
javascript
const [result] = await pool.query(
'UPDATE users SET name = ?, email = ? WHERE id = ?',
[name, email, id]
);
console.log('影响行数:', result.affectedRows);
3.4 删除数据 #
javascript
const [result] = await pool.query('DELETE FROM users WHERE id = ?', [id]);
console.log('影响行数:', result.affectedRows);
四、模型封装 #
4.1 基础模型 #
models/Model.js:
javascript
const pool = require('../config/database').pool;
class Model {
constructor(tableName) {
this.tableName = tableName;
}
async findAll(options = {}) {
let sql = `SELECT * FROM ${this.tableName}`;
const params = [];
if (options.where) {
const conditions = Object.keys(options.where)
.map(key => `${key} = ?`)
.join(' AND ');
sql += ` WHERE ${conditions}`;
params.push(...Object.values(options.where));
}
if (options.order) {
sql += ` ORDER BY ${options.order}`;
}
if (options.limit) {
sql += ` LIMIT ?`;
params.push(options.limit);
}
const [rows] = await pool.query(sql, params);
return rows;
}
async findById(id) {
const [rows] = await pool.query(
`SELECT * FROM ${this.tableName} WHERE id = ?`,
[id]
);
return rows[0];
}
async create(data) {
const keys = Object.keys(data);
const values = Object.values(data);
const placeholders = keys.map(() => '?').join(', ');
const [result] = await pool.query(
`INSERT INTO ${this.tableName} (${keys.join(', ')}) VALUES (${placeholders})`,
values
);
return { id: result.insertId, ...data };
}
async update(id, data) {
const keys = Object.keys(data);
const values = Object.values(data);
const setClause = keys.map(key => `${key} = ?`).join(', ');
const [result] = await pool.query(
`UPDATE ${this.tableName} SET ${setClause} WHERE id = ?`,
[...values, id]
);
return result.affectedRows > 0;
}
async delete(id) {
const [result] = await pool.query(
`DELETE FROM ${this.tableName} WHERE id = ?`,
[id]
);
return result.affectedRows > 0;
}
}
module.exports = Model;
4.2 用户模型 #
models/User.js:
javascript
const Model = require('./Model');
const bcrypt = require('bcryptjs');
class User extends Model {
constructor() {
super('users');
}
async findByEmail(email) {
const [rows] = await pool.query(
'SELECT * FROM users WHERE email = ?',
[email]
);
return rows[0];
}
async create(userData) {
const hashedPassword = await bcrypt.hash(userData.password, 10);
return await super.create({
...userData,
password: hashedPassword
});
}
async comparePassword(plainPassword, hashedPassword) {
return await bcrypt.compare(plainPassword, hashedPassword);
}
async paginate(page = 1, limit = 10) {
const offset = (page - 1) * limit;
const [rows] = await pool.query(
'SELECT id, name, email, role, created_at FROM users LIMIT ? OFFSET ?',
[limit, offset]
);
const [countRows] = await pool.query('SELECT COUNT(*) as total FROM users');
const total = countRows[0].total;
return {
users: rows,
pagination: {
page,
limit,
total,
totalPages: Math.ceil(total / limit)
}
};
}
}
module.exports = new User();
五、事务处理 #
5.1 基本事务 #
javascript
const connection = await pool.getConnection();
try {
await connection.beginTransaction();
await connection.query('INSERT INTO orders (user_id, total) VALUES (?, ?)', [userId, total]);
const [result] = await connection.query('SELECT LAST_INSERT_ID() as id');
const orderId = result[0].id;
for (const item of items) {
await connection.query(
'INSERT INTO order_items (order_id, product_id, quantity) VALUES (?, ?, ?)',
[orderId, item.productId, item.quantity]
);
}
await connection.commit();
return orderId;
} catch (error) {
await connection.rollback();
throw error;
} finally {
connection.release();
}
5.2 事务封装 #
javascript
const transaction = async (callback) => {
const connection = await pool.getConnection();
try {
await connection.beginTransaction();
const result = await callback(connection);
await connection.commit();
return result;
} catch (error) {
await connection.rollback();
throw error;
} finally {
connection.release();
}
};
await transaction(async (conn) => {
await conn.query('INSERT INTO users SET ?', [user]);
await conn.query('INSERT INTO profiles SET ?', [profile]);
});
六、JOIN查询 #
6.1 内连接 #
javascript
const [rows] = await pool.query(`
SELECT users.name, posts.title, posts.content
FROM users
INNER JOIN posts ON users.id = posts.user_id
`);
6.2 左连接 #
javascript
const [rows] = await pool.query(`
SELECT users.name, COUNT(posts.id) as post_count
FROM users
LEFT JOIN posts ON users.id = posts.user_id
GROUP BY users.id
`);
6.3 多表连接 #
javascript
const [rows] = await pool.query(`
SELECT
orders.id,
users.name as customer,
products.name as product,
order_items.quantity
FROM orders
INNER JOIN users ON orders.user_id = users.id
INNER JOIN order_items ON orders.id = order_items.order_id
INNER JOIN products ON order_items.product_id = products.id
`);
七、存储过程 #
7.1 调用存储过程 #
javascript
const [rows] = await pool.query('CALL GetUserOrders(?)', [userId]);
7.2 创建存储过程 #
javascript
await pool.query(`
CREATE PROCEDURE GetUserOrders(IN userId INT)
BEGIN
SELECT * FROM orders WHERE user_id = userId;
END
`);
八、完整示例 #
8.1 用户控制器 #
javascript
const User = require('../models/User');
const { pool } = require('../config/database');
const userController = {
async index(req, res, next) {
try {
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 10;
const { users, pagination } = await User.paginate(page, limit);
res.json({ users, pagination });
} catch (error) {
next(error);
}
},
async show(req, res, next) {
try {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: '用户不存在' });
}
delete user.password;
res.json(user);
} catch (error) {
next(error);
}
},
async store(req, res, next) {
try {
const { name, email, password, role } = req.body;
const existingUser = await User.findByEmail(email);
if (existingUser) {
return res.status(400).json({ error: '邮箱已被注册' });
}
const user = await User.create({ name, email, password, role });
delete user.password;
res.status(201).json(user);
} catch (error) {
next(error);
}
},
async update(req, res, next) {
try {
const { name, email, role } = req.body;
const success = await User.update(req.params.id, { name, email, role });
if (!success) {
return res.status(404).json({ error: '用户不存在' });
}
res.json({ message: '更新成功' });
} catch (error) {
next(error);
}
},
async destroy(req, res, next) {
try {
const success = await User.delete(req.params.id);
if (!success) {
return res.status(404).json({ error: '用户不存在' });
}
res.status(204).send();
} catch (error) {
next(error);
}
}
};
module.exports = userController;
九、总结 #
MySQL集成要点:
| 概念 | 说明 |
|---|---|
| 连接池 | mysql2/promise |
| 查询 | pool.query() |
| 参数化 | 防止SQL注入 |
| 事务 | beginTransaction/commit/rollback |
| JOIN | 多表关联查询 |
下一步,让我们学习ORM使用!
最后更新:2026-03-28