位置: 文档库 > JavaScript > nodejs简单访问及操作mysql数据库的方法示例

nodejs简单访问及操作mysql数据库的方法示例

坚贞不屈 上传于 2023-01-13 13:14

《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初学者和后端开发者参考。