乐趣区

在nodejs中使用mysql2库

参考

  • QQ 群 – Javascript 高级爬虫 – 作者自建群,欢迎加入!
  • awesome-java-crawler – 作者收集的爬虫相关工具和资料
  • 一个帮你自动创建阿里云抢占式实例并开启网络加速的脚本 – 自动创建阿里云海外抢占式节点
  • CentOS 上安装 node.js 二进制发布包 – CentOS 上安装 nodejs 最新版

前言

为何使用 mysql2 而不是经典的 mysql 库?主要基于以下原因:

  1. 更高的性能!
  2. 支持 PreparedStatement,多次查询性能更高,书写 SQL 更简单;
  3. 自带 Promise 包装器,也就是说可以直接使用 async/await 语法;
  4. 绝大部分 api 和 mysql 库兼容,意味着 mysql 的文档和线上资料亦可作为参考。

基本用法

  • 安装
    npm install mysql2
  • 连接数据库

    const conn = await mysql.createConnection({
      host: 'xxxxxxxxxxxxxx.mysql.rds.aliyuncs.com',
      user: '< 数据库用户名 >',
      password: '< 数据库密码 >',
      database: '< 数据库名称 >',
      charset: 'utf8mb4'
    })

    这里字符集用 utf8mb4,这样就可以支持 emoji 表情字符了。

  • 简单查询

    const [rows, fields] = await conn.execute('SELECT * FROM `user` where id = ?', [userId])
    1. 这里用的 execute 函数就是 mysql2 中 PreparedStatement 的使用方式,可以把 sql 语句中的变量用 ’?’ 代替,后面以数组方式依次传入实际值,mysql2 会自动对其进行适当的转换后生成最终的 SQL 语句
    2. execute 返回值为一对数据,即查询到的结果集数组,和结果集元数据,可以用 rows[n].name 形式直接引用结果集中的数据

高级特性

连接池

创建连接池
参数和 createConnection 基本一致,添加了一些池化控制的参数

const pool = mysql.createPool(dbconf)

进程退出时自动关闭连接池

process.on('exit', async (code) => {try { await pool.end() } catch (e) {}})

简单使用
直接用 pool.query(…)和 pool.execute(…)即可,相当于从池中获取一条连接,然后执行查询

事务

从连接池中获取一条连接,开启事务,执行查询和更新,提交事务,归还连接。例子如下:

const conn = await pool.getConnection()
await conn.beginTransaction()
const [rows] = await conn.execute('select * from `activity` where claimed_by is null order by id limit 1 for update')
if (rows.length > 0) {const code = rows[0].code
  await conn.execute('update `activity` set claimed = ?, claimed_by = ? where id = ?', [new Date(), openid, rows[0].id)
  msg = ` 恭喜您!成功抢得礼品卡一张!\n 兑换码为:${code}\n`
} else {msg = '对不起,此次活动的奖品都发完啦!敬请期待下次活动!'}
sendMsg(msg)
await conn.commit()
conn.release()

数据转码

  • mysql/mysql2 提供了 escape 函数用于将数据转码为 SQL 接受的格式,尤其对于用户输入的数据,必须转码处理后再插入数据库,以防御 SQL 注入攻击。
  • escape 会自动把各种原生数据转换为 mysql 接受的数据类型,包括:

    • 字符串自动加单引号,字符串中的特殊字符(尤其是单引号)自动转义
    • Date 类型转换为 ’YYYY-mm-dd HH:ii:ss’ 格式的字符串
    • 数组自动转换成逗号分隔字符串,比如:['a', 'b']转为'a', 'b'
    • undefined/null 转为 NULL
退出移动版