前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nodejs的mysql管理

nodejs的mysql管理

作者头像
OECOM
发布2020-07-01 16:50:59
1.6K0
发布2020-07-01 16:50:59
举报
文章被收录于专栏:OECOM

2019-07-26 14:10:24

nodejs要想操作mysql需要安装第三方库--mysql,有了这个模块,操作mysql数据库就变得很容易了。连接mysql可以说有三种方式,分别是普通模式、连接池模式和集群连接池模式。

踩坑普通模式链接mysql

至于为什么说普通模式时踩坑,下面来看一下普通模式的代码就知道了:

代码语言:javascript
复制
const mysql = require('mysql')
let config = {
    host: '127.0.0.1',
    port: '3306',
    user: 'root',
    password: ''
}
// 连接 mysql 服务器
const connection = mysql.createConnection(config)

// 执行SQL
connection.query(sql, function (err, result) {
  err // 错误信息
  result // 结果
})

// 销毁连接 | 由于 JS 是异步的,所以当前代码会在执行 SQL 之前就销毁了连接
connection.destroy()

如果每次连接数据库都这样写一下会很麻烦,所以一般情况下我们会将其封装起来,作为一个模块儿,供其他的模块调用。

上面的代码示例如果封装起来供其他模块儿调用,会产生一个很大的问题,那就是连接一段时间之后,会与mysql断开连接,造成无法访问数据库的情况,如果重新启动服务,则又可以正常使用了,提示的错误为:nodejs mysql Error: Connection lost The server closed the connection 。 原因在于:MySQL中有一个名叫wait_timeout的变量,表示操作超时时间,当连接超过一定时间没有活动后,会自动关闭该连接,这个值默认为28800(即8小时)。

解决方案

解决方法就是增加重连的机制

代码语言:javascript
复制
function handleError (err) {
  if (err) {
    // 如果是连接断开,自动重新连接
    if (err.code === 'PROTOCOL_CONNECTION_LOST') {
      connect();
    } else {
      console.error(err.stack || err);
    }
  }
}

// 连接数据库,需要将createConnection放到方法里面
function connect () {
  db = mysql.createConnection(config);
  db.connect(handleError);
  db.on('error', handleError);
}

var db;
connect();

这样当检测到链接断开以后,就会自动重新连接了。

推荐使用连接池方式

用 createConnection 创建 Mysql 连接,每执行一次 connection.query 都是一个全新的连接,会造成一个资源的极大浪费,降低性能,如果操作不当还会造成连接中断的情况。连接池是另外的一种执行方法,它一次性的创建了多个连接,然后根据客户端的查询,自动的 分发、复用、管理 这些连接,所以推荐的还是使用连接池的方式来管理mysql

代码语言:javascript
复制
const mysql = require('mysql')
let config = {
    host: '127.0.0.1',
    port: '3306',
    user: 'root',
    password: '',
    charset: "UTF8MB4_GENERAL_CI",
    multipleStatements: true//是否允许一次运行多条sql语句
}

// 链接池:创建多个链接、复用与分发链接
const pool = mysql.createPool(config)

//封装
exports.query = function query(sql, params, callback) {

    pool.getConnection(function (err, conn) {
        if (err) {
            callback(err, null, null);
        } else {
            conn.query(sql, params, function (qerr, vals, fields) {
                conn.release();//释放连接
                callback(qerr, vals, fields); //事件驱动回调
            });
        }
    });
};

从上面的代码示例中,查询封装方法中有三个参数,一个是sql语句,另一个是params,后面一个是回调函数,这种方式应该是被推荐的方式,可以有效地减少sql注入的风险,使用时为:

代码语言:javascript
复制
let sql = "insert into demo (name,sex,age) values(?,?,?)";
let params = ["张三",'男',18]
query.(sql,params,back)

集群连接池模式

连接池集群可以提供多个主机连接,和连接池方法类似,只不过是多个连接池

代码语言:javascript
复制
//创建连接池集群
var poolCluster = mysql.createPoolCluster();
//添加配置 config是一个连接池配置
poolCluster.add(config);//使用自动名称添加配置
poolCluster.add('MASTER',masterConfig);//添加命名配置
poolCluster.add('SLAVE1',slave1config);
poolCluster.add('SLAVE2',slave2config);

//删除配置
poolCluster.remove('SLAVE1');//根据配置名字
poolCluster.remove('SLAVE*')//根据匹配到的

//获取连接 从所有的连接池里获得 默认选择器 
poolCluster.getConnectiuon(function(err,connection){});

//从 一个连接池里面获取连接
poolCluster.getConnectiuon('MASTER',function(err,connection){});
//从匹配到的连接池组里面获取连接 按照顺序
//如果SLAVE1出错 就从SLAVE2获得连接
poolCluster.getConnectiuon('SLAVE*','ORDER',function(err,connection){} );

//触发事件 当删除连接池时触发
poolCluster.on('remove',function(nodeId){
    console.log(nodeId);//被删除的连接池名字
});
//配置 选择器 从SLAVE1 SLAVE2 里面随机获得连接
var pool = poolCluster.of('SLAVE*','RANDOM');
pool.getConnectiuon(function(err,connection){});

//关闭连接池集群
poolCluster.end();
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 踩坑普通模式链接mysql
    • 解决方案
    • 推荐使用连接池方式
    • 集群连接池模式
    相关产品与服务
    云数据库 SQL Server
    腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档