如何在Node.js中使用MySQL进行数据库操作

释放双眼,带上耳机,听听看~!
学习如何在Node.js中使用MySQL进行数据库操作,包括安装和使用mysql和mysql2模块,以及创建数据库和表格

背景

最近在研究怎么进行研发提效的事。业务有这么几个特点:

  1. 插件开发,项目多而小,前后端都没那么难;
  2. 后端绝大多数逻辑都是 CRUD,数据结构也很简单;
  3. 前端 UI 用组件库就行,逻辑基本上就是调用 CRUD 的接口或一些 OpenAPI;

那么针对这些特点,优先提高一下后端的开发效率。每次都新建个 Git Repo,搞一套 CI/CD 实在是太重了。于是我盯上了 FaaS,也就是「云函数」。因为本文的重点不是它,所以就不多扩展了,不知道 FaaS 也不会影响后面的内容,只要知道它直接在云服务提供的浏览器 IDE 里面写一个函数,就能生成一个 API 就可以了。当然也少不了「云数据库」,不知道也没关系,还是不影响后文的理解。

总之,我现在要快速搞一个 CRUD 的项目,来跑一下整个流程。下面来看看我是怎么跟 C 老师对话得到我想要的内容的吧。

总结

因为聊天内容太长了,所以还是先把总结写在前面吧,把聊天记录放到后面大家慢慢看。

  • 首先,最终生成的代码绝对是可以跑的,不过参数还是需要自己修改,所以还是要有一些编程基础啊;
  • 然后,C 老师是真的能帮码农提高效率,我用的还只是 GPT3.5,目前看来效果我已经很满意了;
  • 最后,最最重要的是你得会提问。我也是混了好几天 码农翻身 – ChatGPT 基地 的知识星球,看了好多案例,还自己实践了几天才渐渐掌握诀窍的;

小 Tips:告诉大家个小窍门,最好同时开 2 个以上的 tab,一个专门用来查零碎的小问题,一个保持上下文的干净。很好用。

把我问 C 老师的问题提炼出来,大家先过一下目,实际上也就 10 个问题而已。剩下那么多内容都是 C 老师回答的:

  1. 你是一个非常有经验的程序员,我想向你询问一些编程方面的问题。你可以用专业名词回复我,而不需要解释它们,我自己回去查。你可以优先回答思路和步骤,而不需要马上就返回给我代码。直到我跟你说“请给我代码”,你再把具体代码展示给我。总之,一次回答当中,请尽量全部都是思路或者全部都是代码,而且信息密度要尽量大。如果你明白了,请回复“明白”
  2. 我想在 mysql 中新建一个测试的用户和测试用的db,要怎么做
  3. 我已经安装了 MySQL,现在请告诉我 nodejs 的具体代码
  4. 能不能从新建文件开始,把每一步写的详细一点
  5. npm 包 mysql 和 mysql2 有什么区别?
  6. 那请把上面的例子用 mysql2 再给一遍吧
  7. 请把 morgan 的代码加到上面的 nodejs Demo 代码中,给我展示完整的代码
  8. 上文中 mysql 的 users 表的结构是什么样的
  9. 我现在有了如下服务,请在浏览器的 console 中输入代码,为我创建20条数据,直接给我代码即可 【code】
  10. 请参考下面已有的 3 条数据的格式,为我生成20条模拟数据,静态数据即可,不需要用代码动态生成:【code】

下面就是比较完整的聊天记录了,大家慢慢看~~

聊天过程 TL;DR

注:我将一些不成功的提问过滤掉了,留下的都是比较关键的有用的提问。

1. 先给它角色

来自你的消息:

你是一个非常有经验的程序员,我想向你询问一些编程方面的问题。你可以用专业名词回复我,而不需要解释它们,我自己回去查。你可以优先回答思路和步骤,而不需要马上就返回给我代码。直到我跟你说“请给我代码”,你再把具体代码展示给我。总之,一次回答当中,请尽量全部都是思路或者全部都是代码,而且信息密度要尽量大。如果你明白了,请回复“明白”

来自 ChatGPT 的消息:

明白。

2. 先把 MySQL 准备好

安装什么的我就省略了,其实我开了另一个 tab 来问这些零碎的问题,以免主 tab 中的上下文太混乱。

来自你的消息:

我想在 mysql 中新建一个测试的用户和测试用的db,要怎么做

来自 ChatGPT 的消息:

你可以按照以下步骤在 MySQL 中新建一个测试用户和测试数据库:

  1. 以超级用户(如 root 用户)连接到 MySQL 服务器,可以使用以下命令连接:

    mysql -u root -p
    

    然后输入超级用户的密码进行身份验证。

  2. 创建一个新的数据库,可以使用以下命令:

    CREATE DATABASE testdb;
    

    这将创建一个名为 testdb 的数据库。

  3. 创建一个新的用户,可以使用以下命令:

    CREATE USER 'testuser'@'localhost' IDENTIFIED BY 'mypassword';
    

    这将创建一个名为 testuser 的用户,并使用密码 mypassword 进行身份验证。其中,'localhost' 表示该用户只能从本地进行连接。

  4. 将 testuser 用户赋予访问 testdb 数据库的权限,可以使用以下命令:

    GRANT ALL PRIVILEGES ON testdb.* TO 'testuser'@'localhost';
    

    这将使 testuser 用户拥有访问 testdb 数据库的所有权限。

  5. 退出 MySQL 客户端,可以使用以下命令:

    EXIT;
    

现在,你已经成功创建了一个名为 testuser 的用户,以及一个名为 testdb 的数据库,并且授予了 testuser 用户访问 testdb 数据库的权限。你可以使用以下命令来连接到 MySQL 服务器并使用 testuser 用户访问 testdb 数据库:

mysql -u testuser -p testdb

然后输入 testuser 用户的密码进行身份验证。

3. 接下来让 Nodejs 和 MySQL 连起来

来自你的消息:

我已经安装了 MySQL,现在请告诉我 nodejs 的具体代码

来自 ChatGPT 的消息:

好的,Node.js 连接 MySQL 数据库的基本步骤如下:

  1. 安装 mysql2 模块

在终端中运行以下命令来安装 mysql2 模块:

npm install mysql2
  1. 在程序中连接 MySQL 数据库

使用以下代码连接 MySQL 数据库:

const mysql = require('mysql2');

// 创建连接池
const pool = mysql.createPool({
    host: 'localhost',  // 数据库地址
    user: 'root',       // 数据库用户
    password: 'password',  // 数据库密码
    database: 'database_name',  // 数据库名称
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
});

// 使用连接池查询数据
pool.query('SELECT * FROM your_table_name', function (err, results, fields) {
    if (err) throw err;
    console.log(results);
});

这里,你需要将数据库地址、数据库用户、数据库密码和数据库名称替换为你自己的数据。

在以上代码中,我们先创建了一个连接池,然后通过连接池来查询数据库,MySQL 连接池是一种重用连接的技术,对于高并发的请求能更快的响应,同时具有更好的可扩展性。

来自你的消息:

能不能从新建文件开始,把每一步写的详细一点

来自 ChatGPT 的消息:

当然可以,我们从头开始一步一步地搭建一个带 MySQL 数据库的 Node.js 服务:

  1. 首先,打开终端,使用命令行工具创建一个新的文件夹,例如使用以下指令:
mkdir my-node-app
  1. 然后,进入这个文件夹,使用以下命令初始化一个 Node.js 项目:
cd my-node-app
npm init

在运行 npm init 命令时会提示你输入一些项目信息,例如项目名称、描述、作者等等。你可以根据自己的需要自行填写。

  1. 接下来,我们需要在项目中安装 MySQL 驱动程序,使用以下命令在项目中安装 mysql 模块:
npm install mysql
  1. 安装完成后,在根目录创建一个名为 index.js 的文件,并在文件中引入 mysql 模块:
const mysql = require('mysql');
  1. 接着,我们需要连接到 MySQL 数据库。可以先创建一个连接池,便于我们重复使用数据库连接。连接池可以自动管理连接的创建和释放,避免频繁地创建和销毁连接,提高性能。以下是示例代码:
const pool = mysql.createPool({
  connectionLimit: 10,
  host: 'localhost',
  user: 'root',
  password: 'password', // 这里需要修改为你自己的密码
  database: 'my_database' // 这里需要修改为你自己的数据库名
});

解释一下上面的代码,其中 connectionLimit 用于设置连接池的最大连接数,host 用于设置 MySQL 数据库的主机名或 IP 地址,userpassword 分别对应 MySQL 数据库的用户名和密码,database 对应连接的数据库名。你需要根据自己的具体情况修改这些配置。

  1. 最后,在回调函数中执行 SQL 查询语句。以下是一个简单的查询示例,该查询语句会查询一个名为 users 的表中的所有行:
pool.getConnection((err, connection) => {
  if (err) throw err; // 查询失败抛出异常
  const sql = 'SELECT * FROM users';
  connection.query(sql, (error, results, fields) => {
    connection.release(); // 释放连接
    if (error) throw error; // 查询失败抛出异常
    console.log(results); // 输出查询结果
  });
});

解释一下上面的代码,getConnection 方法实现从连接池中获取一个连接,执行查询之前需要获取一个连接。query 方法执行 SQL 查询语句,查询完成后需要释放连接(使用 release() 方法)以便连接池可以重复使用这个连接。results 参数对应查询结果,fields 参数对应所有字段的元数据信息。

到这里为止,我们已经完成了一个带 MySQL 数据库的 Node.js 服务的搭建过程。如果你想要更深入地了解 Node.js 和 MySQL 数据库的相关内容,可以参考官方文档或者各种在线教程。

4. 小插曲 – 把 C 老师拉回 mysql2

注:这块出了点小状况。C 老师一会用 mysql2 一会用 mysql,有点乱。想了想还是把这段留下来,也算是给大家一个参考,看我是怎么把它拉回来的。其实我问的问题不多,但是它回答的内容比较多,各位可以快速扫一下就行了。

来自你的消息:

npm 包 mysql 和 mysql2 有什么区别?

来自 ChatGPT 的消息:

mysqlmysql2 都是 Node.js 中连接 MySQL 数据库的第三方库,它们的主要区别在于性能和功能特性。

mysql 是连接 MySQL 最常见的 Node.js 库之一,因为它是最早的 Node.js MySQL 驱动程序之一。它可以连接 MySQL 数据库并执行查询,但是它在处理多个查询时性能比较低,并且它不支持异步/等待接口。

相比之下,mysql2 这个包致力于提供更高的性能和全面的特性。与 mysql 不同的是,mysql2 是一个使用纯 JavaScript 编写的库,并支持很多额外的功能,例如:支持 promises、streaming resultsets、复制流和支持视图,同时避免了在执行查询语句时被攻击者利用。

因此,如果您需要高性能和全面的特性,那么建议使用 mysql2 来连接 MySQL 数据库。但是如果你的应用程序需要与一个老的,只支持 mysql 的版本兼容,或者你不需要 mysql2 的某些特性,那么还可以继续使用 mysql

来自你的消息:

那请把上面的例子用 mysql2 再给一遍吧

来自 ChatGPT 的消息:

好的,以下是使用 mysql2 来查询 MySQL 数据库并返回结果的示例代码:

const mysql = require('mysql2');

const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'database_name',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
});

function queryDatabase(sql, params, callback) {
  pool.query(sql, params, function (error, results, fields) {
    if (error) {
      return callback(error, null);
    }
    return callback(null, results);
  });
}

// 使用示例
const sql = 'SELECT * FROM table_name WHERE id = ?';
const params = [1];
queryDatabase(sql, params, function (error, results) {
  if (error) {
    console.log(error);
    return;
  }
  console.log(results);
});

上面的代码示例中,我们使用 mysql2 来创建连接池,并通过连接池来查询数据库。注意,mysql2 支持使用参数占位符(?)来防止 SQL 注入攻击。当查询执行完成后,我们调用回调函数来释放连接并返回查询结果。

5. 第一版比较完整的代码

注:这块省略了一段加 morgan 日志的对话,不耽误。

来自你的消息:

请把 morgan 的代码加到上面的 nodejs Demo 代码中,给我展示完整的代码

来自 ChatGPT 的消息:

好的,请参考下面的完整代码,我已经加入了 morgan 中间件并进行了相应的注释:

// 引入必备模块
const express = require('express');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const morgan = require('morgan'); // 引入 morgan 中间件

// 创建 express 应用
const app = express();

// 使用 body-parser 中间件来解析请求体中的 JSON 数据
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// 使用 morgan 中间件来记录每一次请求的信息
app.use(morgan('combined'));

// 创建一个 MySQL 数据库连接池
const pool = mysql.createPool({
  connectionLimit: 10, // 最多同时处理 10 个连接请求
  host: 'localhost', // 数据库服务器的地址
  user: 'root', // 登录数据库的用户名
  password: 'password', // 登录数据库的密码
  database: 'test', // 要连接的数据库的名字
});

// GET 请求的处理程序
app.get('/users', (req, res) => {
  // 因为通过 URL 查询字符串也可以传递客户端数据,所以这里也解析一下查询字符串中的参数
  const { name } = req.query;

  // 查询数据
  let sql = 'SELECT * FROM users';
  if (name) {
    sql += ` WHERE name LIKE '%${name}%'`;
  }
  pool.query(sql, (error, results) => {
    if (error) {
      res.status(500).send(error);
    } else {
      res.send(results);
    }
  });
});

// POST 请求的处理程序
app.post('/users', (req, res) => {
  // 获取客户端提交的数据
  const { name, email } = req.body;

  // 把数据插入到数据库中
  pool.query('INSERT INTO users SET ?', { name, email }, (error, results) => {
    if (error) {
      res.status(500).send(error);
    } else {
      res.send(results);
    }
  });
});

// PUT 请求的处理程序
app.put('/users/:id', (req, res) => {
  // 获取客户端提交的数据和 URL 中的参数
  const { id } = req.params;
  const { name, email } = req.body;

  // 更新指定 ID 的数据
  pool.query('UPDATE users SET ? WHERE id = ?', [{ name, email }, id], (error, results) => {
    if (error) {
      res.status(500).send(error);
    } else {
      res.send(results);
    }
  });
});

// DELETE 请求的处理程序
app.delete('/users/:id', (req, res) => {
  // 获取 URL 中的参数
  const { id } = req.params;

  // 删除指定 ID 的数据
  pool.query('DELETE FROM users WHERE id = ?', id, (error, results) => {
    if (error) {
      res.status(500).send(error);
    } else {
      res.send(results);
    }
  });
});

// 启动服务器
app.listen(3000, () => {
  console.log('Server is running at http://localhost:3000');
});

以上就是完整代码,如果您需要对接自己的 MySQL 数据库,需要修改 hostuserpassworddatabase 这四个参数,分别代表数据库服务器的地址、登录数据库的用户名、密码和要连接的数据库的名字。

6. 竟然还没建表

注:先有了代码,后建的表,好像跟平时工作相反哈。不过仔细想想,这才是正常的思维啊,现有业务的描述,然后才能想出来怎么建表嘛。只不过我们在描述业务的过程中,已经把代码提前写出来了而已。

来自你的消息:

上文中 mysql 的 users 表的结构是什么样的

来自 ChatGPT 的消息:

很抱歉我没有提供相关信息,下面是 users 表的结构。

CREATE TABLE users (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(50) NOT NULL,
  email VARCHAR(100) NOT NULL UNIQUE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

这个 SQL 语句会在 MySQL 数据库中创建一个名为 users 的表,它包含三个列:id、name 和 email。其中,id 是一个自增的整数,作为主键,name 和 email 都是必填项,email 还需要保证唯一性。该表使用 InnoDB 引擎,字符集为 utf8mb4,使用 utf8mb4_unicode_ci 算法进行比较和排序。

7. 调用接口试试,顺便多生成几条数据

注:这块 C 老师好像把上下文忘了,只能我手动给它补上了。另外,生成的代码因为 async/await 的语法原因,还不能直接在 console 里运行,还是需要小改一下的。只要去掉 async,把 await 改成 promise 的写法就行了。这里就留个动手题大家自己试一下吧。

来自你的消息:

我现在有了如下服务,请在浏览器的 console 中输入代码,为我创建20条数据,直接给我代码即可

// 引入必备模块
const express = require('express');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const morgan = require('morgan'); // 引入 morgan 中间件

// 创建 express 应用
const app = express();

// 使用 body-parser 中间件来解析请求体中的 JSON 数据
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// 使用 morgan 中间件来记录每一次请求的信息
app.use(morgan('combined'));

// 创建一个 MySQL 数据库连接池
const pool = mysql.createPool({
  connectionLimit: 10, // 最多同时处理 10 个连接请求
  host: 'localhost', // 数据库服务器的地址
  user: 'root', // 登录数据库的用户名
  password: 'password', // 登录数据库的密码
  database: 'test', // 要连接的数据库的名字
});

// GET 请求的处理程序
app.get('/users', (req, res) => {
  // 因为通过 URL 查询字符串也可以传递客户端数据,所以这里也解析一下查询字符串中的参数
  const { name } = req.query;

  // 查询数据
  let sql = 'SELECT * FROM users';
  if (name) {
    sql += ` WHERE name LIKE '%${name}%'`;
  }
  pool.query(sql, (error, results) => {
    if (error) {
      res.status(500).send(error);
    } else {
      res.send(results);
    }
  });
});

// POST 请求的处理程序
app.post('/users', (req, res) => {
  // 获取客户端提交的数据
  const { name, email } = req.body;

  // 把数据插入到数据库中
  pool.query('INSERT INTO users SET ?', { name, email }, (error, results) => {
    if (error) {
      res.status(500).send(error);
    } else {
      res.send(results);
    }
  });
});

// PUT 请求的处理程序
app.put('/users/:id', (req, res) => {
  // 获取客户端提交的数据和 URL 中的参数
  const { id } = req.params;
  const { name, email } = req.body;

  // 更新指定 ID 的数据
  pool.query('UPDATE users SET ? WHERE id = ?', [{ name, email }, id], (error, results) => {
    if (error) {
      res.status(500).send(error);
    } else {
      res.send(results);
    }
  });
});

// DELETE 请求的处理程序
app.delete('/users/:id', (req, res) => {
  // 获取 URL 中的参数
  const { id } = req.params;

  // 删除指定 ID 的数据
  pool.query('DELETE FROM users WHERE id = ?', id, (error, results) => {
    if (error) {
      res.status(500).send(error);
    } else {
      res.send(results);
    }
  });
});

// 启动服务器
app.listen(3000, () => {
  console.log('Server is running at http://localhost:3000');
});

来自 ChatGPT 的消息:

以下是用 fetch 函数向服务器批量创建20条数据的代码:

// 定义函数,用于发送 POST 请求并创建数据
async function createUsers() {
  const endpoint = 'http://localhost:3000/users';
  const headers = { 'Content-Type': 'application/json' };
  const data = [
    { name: 'Alice', email: 'alice@example.com' },
    { name: 'Bob', email: 'bob@example.com' },
    { name: 'Charlie', email: 'charlie@example.com' },
    // ...还有17条数据
  ];

  try {
    const response = await fetch(endpoint, {
      method: 'POST',
      headers,
      body: JSON.stringify(data),
    });
    const result = await response.json();
    console.log('创建成功:', result);
  } catch (error) {
    console.error('创建失败:', error);
  }
}

// 调用函数,创建数据
createUsers();

注意:以上代码需要在浏览器的 console 中执行,而不是在服务器端编写和运行。

来自你的消息:

请参考下面已有的 3 条数据的格式,为我生成20条模拟数据,静态数据即可,不需要用代码动态生成:

const data = [
{ name: ‘Alice’, email: ‘alice@example.com‘ },
{ name: ‘Bob’, email: ‘bob@example.com‘ },
{ name: ‘Charlie’, email: ‘charlie@example.com‘ },
// …还有17条数据
];

来自 ChatGPT 的消息:

根据上述数据格式,以下是生成20条静态数据的一种方法:

const data = [
  { name: 'Alice', email: 'alice@example.com' },
  { name: 'Bob', email: 'bob@example.com' },
  { name: 'Charlie', email: 'charlie@example.com' },
  { name: 'David', email: 'david@example.com' },
  { name: 'Emma', email: 'emma@example.com' },
  { name: 'Frank', email: 'frank@example.com' },
  { name: 'Grace', email: 'grace@example.com' },
  { name: 'Hannah', email: 'hannah@example.com' },
  { name: 'Ian', email: 'ian@example.com' },
  { name: 'Jane', email: 'jane@example.com' },
  { name: 'Kate', email: 'kate@example.com' },
  { name: 'Liam', email: 'liam@example.com' },
  { name: 'Mandy', email: 'mandy@example.com' },
  { name: 'Nina', email: 'nina@example.com' },
  { name: 'Oliver', email: 'oliver@example.com' },
  { name: 'Peter', email: 'peter@example.com' },
  { name: 'Rose', email: 'rose@example.com' },
  { name: 'Samantha', email: 'samantha@example.com' },
  { name: 'Tom', email: 'tom@example.com' },
  { name: 'Victoria', email: 'victoria@example.com' }
];

另外,以下是另一种生成20条静态数据的方法:

const data = Array.from({ length: 20 }, (_, i) => ({
  name: `User ${i + 1}`,
  email: `user${i + 1}@example.com`
}));

请让我知道需要返回给你哪一种方法的具体代码。

彩蛋

恭喜你能够耐心的看到最后,作为奖励,我把我复盘之后总结出来的咒语告诉你吧,效果特别的好:

我现在想新建个 express + mysql2 的服务,要求:

  1. 目录结构尽量科学,文件拆分合理
  2. 用 commonjs 的方式写
  3. 模拟一个 mysql 的 users 表,有 id,name,email 属性
  4. express 服务实现对 users 表的增删改查 API

请先列出来目录结构,然后挨个 js 文件展示代码,只需要返回代码,不需要解释任何事情。

如何在Node.js中使用MySQL进行数据库操作

本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

实现 ChatGPT 的打字机效果及 SSE 接口示例

2023-12-18 19:56:14

AI教程

可控文本生成:深度学习方法的发展与应用

2023-12-18 20:01:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索