基于原生sql在node中使用mysql模块进行sql封装【一】

796 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第22天,点击查看活动详情

前情提要

  • Node.js属于前端人的福音,可以几乎无缝衔接的去接触后端,而不用像转头去学习java,python,go等这样的老大哥级别的后端语言所需耗费那么大的学习成本。
  • Node可以让我们前端人不再强依赖后端开发人员,比如有些时候接口还没有出来的时候,我们就可以自己写接口。
  • Node也可以让我们自己做项目,接私活等不再担忧没有后端人员配合的问题,有啥问题直接js一套自己就带走了。
  • 那么接触了后端,mysql便成了不可少的一个环节。Node该如何连接mysql数据库呢?
  • 安装方式:npm i mysql -s

mysql连接数据库

  • 第一种:执行一次sql语句就进行一次连接和关闭封装方式
    • 代码示例:

      const mysql = require('mysql);
      let connection = mysql.createConnection({
          host:'localhost', // 数据库ip地址
          user: 'root', // 数据库用户名
          password: 'xxxx', // 数据库密码
          port: '3306', // 端口号,默认是3306
          database: 'yyyy', // 要连接的数据库名称
          multipleStatements: true // 是否执行多条sql语句
      });
      let query  = (sql) => {
          return new Promise((resolve, reject) => {
              connection.connect(); // 连接数据库
              connection.query(sql, function(err, result) => {
                  if (err) reject(err);
                  else resolve(JSON.parse(JSON.stringify(result))) // 返回的数据一般情况下是字符串,所以需要经过序列化数据,然后就能拿到json类型的数据了。
              })
              connection.end(); // 关闭连接;end方法接收一个方法回调。
              // 以上可以写成: connection.end(function(err) {console.log(err)})
              // 也可以销毁连接:connection.destroy(),不过该方法没有方法回调哦
          })
       }
       // 最后将封装的query方法暴露出去
       module.exports = query
      
    • 注意:

      • 为了安全,还需要对sql进行特殊处理,用以防止sql注入的网络攻击。
      • 如果需要使用ssl连接,那么可以在创建连接的时候增加ssl: {ca: '文件地址'}
      • 缺点:该方法会出现频繁的创建连接,执行完之后会立马关闭连接。如果出现并发的情况,那么将会出现很大的性能开销问题。
  • 第二种:使用连接池来进行sql方法封装。
    • 思路:起初会跟第一种方式一样,被调用的时候会创建连接,然后去执行sql,可以设置可以同时存在多少条连接,超过数量会进入等待状态。一个连接执行完sql后并不会立马关闭,而是检测是否还有sql在等待执行,如果有就继续执行,如果一段时间后便会关闭。这种方式主要对并发的时候比较友好。

    • 代码示例:

      const mysql = require('mysql');
      let con = mysql.createPool({
          // 此处和创建连接时的参数差不多,就不再多做赘述。
      })
      let query = (sql) => {
          return new Promise((resolve, reject) => {
              con.getConnection(function(err, connection) {
                  if (err) reject(err);
                  connection.query(sql, (err, result) => {
                      if (err) reject(err);
                      else resolve(JSON.parse(JSON.stringify(rows)));
                      // 查询完之后释放连接
                      connection.release();
                  })
              })
          })
      }
      module.exports = query;
      
    • 注意

      • 要注意防止sql注入攻击
      • 关于ssl的设置与上面一样呦

总结

  • 根据实际业务场景中,时长会遇到数据库的频繁操作,所以如果使用第一种方法即用即连即关的方式,那么会造成查询时间延迟的问题,对系统的性能开销也会增加。如果使用第二种连接池,那么便可以优化这个问题。所以强烈推荐第二种封装的方法。
  • 网络安全不可小觑,所以一定要对用户传过来的字段内容做处理,否则很容易被攻破数据库。小编在云服务器上得数据库就被黑客攻破过...,所以不可小觑,测试服务器里的测试数据倒也无所谓,但是如果是正式环境那将是灾难级的。
  • 针对如何防止sql注入,后面会单独出篇文章。