《Node.js简单访问及操作MySQL数据库的方法示例》
在Node.js开发中,数据库操作是构建后端服务的核心环节之一。MySQL作为广泛使用的关系型数据库,通过Node.js可以高效实现数据的增删改查(CRUD)。本文将详细介绍如何使用Node.js连接MySQL数据库,完成基础操作,并附上完整代码示例,帮助开发者快速上手。
一、环境准备
在开始前,需确保已安装以下工具:
- Node.js(建议版本14+)
- MySQL数据库(本地或远程)
- 代码编辑器(如VS Code)
通过npm安装MySQL驱动包:
npm install mysql
此包是Node.js操作MySQL的官方推荐驱动,提供同步和异步两种调用方式。
二、连接MySQL数据库
连接数据库需配置主机、端口、用户名、密码和数据库名。以下是一个基础连接示例:
const mysql = require('mysql');
// 创建连接配置
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'yourpassword',
database: 'testdb'
});
// 建立连接
connection.connect(err => {
if (err) {
console.error('连接失败:', err.stack);
return;
}
console.log('连接成功,ID:', connection.threadId);
});
// 关闭连接(通常在操作完成后)
// connection.end();
上述代码中,createConnection
方法创建连接对象,connect
方法触发实际连接。建议将配置信息提取到环境变量中,避免硬编码。
三、执行SQL查询
MySQL驱动支持直接执行SQL语句。以下演示查询操作:
1. 查询数据
connection.query('SELECT * FROM users', (err, results, fields) => {
if (err) throw err;
console.log('查询结果:', results);
});
回调函数参数说明:
-
err
: 错误对象(无错误时为null) -
results
: 查询返回的数据数组 -
fields
: 字段信息(通常忽略)
2. 参数化查询(防SQL注入)
直接拼接SQL字符串存在安全风险,应使用参数化查询:
const userId = 1;
connection.query('SELECT * FROM users WHERE id = ?', [userId], (err, results) => {
if (err) throw err;
console.log('用户信息:', results[0]);
});
问号?
为占位符,驱动会自动转义参数,避免SQL注入攻击。
四、插入数据
插入数据需指定表名和字段值:
const user = {
name: '张三',
email: 'zhangsan@example.com',
age: 25
};
connection.query('INSERT INTO users SET ?', user, (err, result) => {
if (err) throw err;
console.log('插入成功,ID:', result.insertId);
});
此处使用SET ?
语法,对象属性名需与数据库字段名一致。result.insertId
返回自动生成的主键值。
五、更新数据
更新操作需指定条件字段:
const updateData = { age: 26 };
const condition = { id: 1 };
connection.query('UPDATE users SET ? WHERE ?', [updateData, condition], (err, result) => {
if (err) throw err;
console.log('更新影响行数:', result.affectedRows);
});
affectedRows
属性表示被修改的记录数,可用于判断操作是否成功。
六、删除数据
删除操作与更新类似:
const deleteCondition = { id: 2 };
connection.query('DELETE FROM users WHERE ?', deleteCondition, (err, result) => {
if (err) throw err;
console.log('删除影响行数:', result.affectedRows);
});
删除前建议先查询确认数据是否存在,避免误删。
七、使用连接池优化性能
频繁创建和销毁连接会消耗资源,连接池可复用连接:
const pool = mysql.createPool({
connectionLimit: 10, // 最大连接数
host: 'localhost',
user: 'root',
password: 'yourpassword',
database: 'testdb'
});
// 从连接池获取连接
pool.getConnection((err, connection) => {
if (err) throw err;
connection.query('SELECT * FROM users', (err, results) => {
connection.release(); // 释放连接回池
if (err) throw err;
console.log(results);
});
});
连接池自动管理连接生命周期,适合高并发场景。
八、异步操作与Promise封装
回调函数可能导致代码嵌套过深,可通过Promise封装:
function queryPromise(sql, params) {
return new Promise((resolve, reject) => {
pool.query(sql, params, (err, results) => {
if (err) reject(err);
else resolve(results);
});
});
}
// 使用示例
async function getUserById(id) {
try {
const results = await queryPromise('SELECT * FROM users WHERE id = ?', [id]);
return results[0];
} catch (err) {
console.error('查询失败:', err);
}
}
getUserById(1).then(user => console.log(user));
结合async/await
语法,代码更清晰易读。
九、完整示例:用户管理系统
以下是一个集成CRUD操作的完整示例:
const mysql = require('mysql');
// 创建连接池
const pool = mysql.createPool({
connectionLimit: 10,
host: 'localhost',
user: 'root',
password: 'yourpassword',
database: 'testdb'
});
// 封装查询方法
async function executeQuery(sql, params = []) {
const connection = await pool.getConnectionAsync(); // 假设已封装Promise
try {
const [results] = await connection.promise().query(sql, params);
return results;
} finally {
connection.release();
}
}
// 创建用户
async function createUser(user) {
const sql = 'INSERT INTO users SET ?';
const result = await executeQuery(sql, user);
return result.insertId;
}
// 查询用户
async function getUser(id) {
const sql = 'SELECT * FROM users WHERE id = ?';
const results = await executeQuery(sql, [id]);
return results[0];
}
// 更新用户
async function updateUser(id, updates) {
const sql = 'UPDATE users SET ? WHERE id = ?';
await executeQuery(sql, [updates, id]);
}
// 删除用户
async function deleteUser(id) {
const sql = 'DELETE FROM users WHERE id = ?';
await executeQuery(sql, [id]);
}
// 测试
(async () => {
try {
const newUserId = await createUser({ name: '李四', email: 'lisi@example.com' });
console.log('创建用户ID:', newUserId);
const user = await getUser(newUserId);
console.log('查询用户:', user);
await updateUser(newUserId, { age: 30 });
console.log('更新完成');
await deleteUser(newUserId);
console.log('删除完成');
} catch (err) {
console.error('操作失败:', err);
}
})();
十、常见问题与解决方案
1. 连接超时:检查MySQL服务是否运行,配置中的主机和端口是否正确。
2. 权限错误:确保数据库用户有操作权限,使用GRANT
语句授权。
3. 字符集问题:在连接配置中添加charset: 'utf8mb4'
避免中文乱码。
4. 连接泄漏:使用连接池并确保每次操作后释放连接。
十一、总结
本文通过实例演示了Node.js操作MySQL的核心流程,包括连接管理、CRUD操作、安全防护和性能优化。关键点如下:
- 使用
mysql
包建立连接 - 通过参数化查询防止SQL注入
- 优先使用连接池提升性能
- 结合Promise和async/await简化异步代码
掌握这些基础后,可进一步学习事务处理、ORM框架(如Sequelize)和数据库迁移工具,构建更复杂的后端服务。
关键词:Node.js、MySQL、数据库操作、CRUD、连接池、异步编程、参数化查询、SQL注入防护
简介:本文详细介绍了Node.js通过mysql包连接和操作MySQL数据库的方法,涵盖环境配置、连接管理、增删改查操作、安全防护及性能优化,提供完整代码示例和常见问题解决方案,适合Node.js初学者和后端开发者参考。