zoukankan      html  css  js  c++  java
  • 用Nodejs连接MySQL

    首先需要自己安装mysql数据库 不会的找一个集成包就可以

    然后才能接着下面的事情~

    建立MySQL测试库

    本地创建MySQL测试库:nodejs

    ~ mysql -uroot -p
    mysql> CREATE DATABASE nodejs;
    mysql> SHOW DATABASES;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | nodejs             |
    | performance_schema |
    +--------------------+
    4 rows in set (0.00 sec)
    
    mysql> GRANT ALL ON nodejs.* to nodejs@'%' IDENTIFIED BY 'nodejs';
    mysql> GRANT ALL ON nodejs.* to nodejs@localhost IDENTIFIED BY 'nodejs';
    

      

    node-mysql安装

    第一个测试

    ~ vi app.js
    
    var mysql = require('mysql');
    var conn = mysql.createConnection({
        host: 'localhost',
        user: '你的用户名 默认root',
        password: '你的mysql密码',
        database:'nodejs',
        port: 3306
    });
    conn.connect();
    conn.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
        if (err) throw err;
        console.log('The solution is: ', rows[0].solution);
    });
    conn.end();
    

      

    运行

    node app.js
    The solution is:  2

    此时已经说明已经正常链接到MySql了

    node-mysql使用

    下面我们要对node-mysql的API进行常用的测试。

    • 表新删改查
    • 连接池配置
    • MySQL断线重连
    • 连接池超时测试

    1). 表新删改查
    修改app.js

    
    ~ vi app.js
    
    var mysql = require('mysql');
    var conn = mysql.createConnection({
        host: 'localhost',
        user: 'nodejs',
        password: 'nodejs',
        database: 'nodejs',
        port: 3306
    });
    conn.connect();
    
    var insertSQL = 'insert into t_user(name) values("conan"),("fens.me")';
    var selectSQL = 'select * from t_user limit 10';
    var deleteSQL = 'delete from t_user';
    var updateSQL = 'update t_user set name="conan update"  where name="conan"';
    
    //delete
    conn.query(deleteSQL, function (err0, res0) {
        if (err0) console.log(err0);
        console.log("DELETE Return ==> ");
        console.log(res0);
    
        //insert
        conn.query(insertSQL, function (err1, res1) {
            if (err1) console.log(err1);
            console.log("INSERT Return ==> ");
            console.log(res1);
    
            //query
            conn.query(selectSQL, function (err2, rows) {
                if (err2) console.log(err2);
    
                console.log("SELECT ==> ");
                for (var i in rows) {
                    console.log(rows[i]);
                }
    
                //update
                conn.query(updateSQL, function (err3, res3) {
                    if (err3) console.log(err3);
                    console.log("UPDATE Return ==> ");
                    console.log(res3);
    
                    //query
                    conn.query(selectSQL, function (err4, rows2) {
                        if (err4) console.log(err4);
    
                        console.log("SELECT ==> ");
                        for (var i in rows2) {
                            console.log(rows2[i]);
                        }
                    });
                });
            });
        });
    });
    
    //conn.end();
    

    控制台输出:

    D:workspacejavascript
    odejs-node-mysql>node app.js
    DELETE Return ==>
    { fieldCount: 0,
      affectedRows: 2,
      insertId: 0,
      serverStatus: 34,
      warningCount: 0,
      message: '',
      protocol41: true,
      changedRows: 0 }
    INSERT Return ==>
    { fieldCount: 0,
      affectedRows: 2,
      insertId: 33,
      serverStatus: 2,
      warningCount: 0,
      message: '&Records: 2  Duplicates: 0  Warnings: 0',
      protocol41: true,
      changedRows: 0 }
    SELECT ==>
    { id: 33,
      name: 'conan',
      create_date: Wed Sep 11 2013 12:09:15 GMT+0800 (中国标准时间) }
    { id: 34,
      name: 'fens.me',
      create_date: Wed Sep 11 2013 12:09:15 GMT+0800 (中国标准时间) }
    UPDATE Return ==>
    { fieldCount: 0,
      affectedRows: 1,
      insertId: 0,
      serverStatus: 2,
      warningCount: 0,
      message: '(Rows matched: 1  Changed: 1  Warnings: 0',
      protocol41: true,
      changedRows: 1 }
    SELECT ==>
    { id: 33,
      name: 'conan update',
      create_date: Wed Sep 11 2013 12:09:15 GMT+0800 (中国标准时间) }
    { id: 34,
      name: 'fens.me',
      create_date: Wed Sep 11 2013 12:09:15 GMT+0800 (中国标准时间) }
    

    由于node的异步的,上面是一个连续的操作,代码会被写的支离破碎。我们可以通过async库对上面代码进行封装,请参考文章:Nodejs异步流程控制Async

    2). 连接池配置

    增加文件:app-pooling.js

    ~ vi app-pooling.js
    
    var mysql = require('mysql');
    var pool = mysql.createPool({
        host: 'localhost',
        user: 'nodejs',
        password: 'nodejs',
        database: 'nodejs',
        port: 3306
    });
    
    var selectSQL = 'select * from t_user limit 10';
    
    pool.getConnection(function (err, conn) {
        if (err) console.log("POOL ==> " + err);
    
        conn.query(selectSQL,function(err,rows){
            if (err) console.log(err);
            console.log("SELECT ==> ");
            for (var i in rows) {
                console.log(rows[i]);
            }
            conn.release();
        });
    });
    

    控制台输出:

    D:workspacejavascript
    odejs-node-mysql>node app-pooling.js
    SELECT ==>
    { id: 39,
      name: 'conan update',
      create_date: Wed Sep 11 2013 13:41:18 GMT+0800 (中国标准时间) }
    { id: 40,
      name: 'fens.me',
      create_date: Wed Sep 11 2013 13:41:18 GMT+0800 (中国标准时间) }
    

    3). MySQL断线重连

    分别模拟3种错误

    • 登陆密码错误
    • 数据库宕机
    • 数据库连接超时

    新增文件:app-reconnect.js

    ~ vi app-reconnect.js
    
    var mysql = require('mysql');
    var conn;
    function handleError () {
        conn = mysql.createConnection({
            host: 'localhost',
            user: 'nodejs',
            password: 'nodejs',
            database: 'nodejs',
            port: 3306
        });
    
        //连接错误,2秒重试
        conn.connect(function (err) {
            if (err) {
                console.log('error when connecting to db:', err);
                setTimeout(handleError , 2000);
            }
        });
    
        conn.on('error', function (err) {
            console.log('db error', err);
            // 如果是连接断开,自动重新连接
            if (err.code === 'PROTOCOL_CONNECTION_LOST') {
                handleError();
            } else {
                throw err;
            }
        });
    }
    handleError();
    

    a. 模拟密码错误

    修改password: ‘nodejs11’

    控制台输出。

    D:workspacejavascript
    odejs-node-mysql>node app-reconnect.js
    error when connecting to db: { [Error: ER_ACCESS_DENIED_ERROR: Access denied for user 'nodejs'@'localhost' (using pass
    rd: YES)]
      code: 'ER_ACCESS_DENIED_ERROR',
      errno: 1045,
      sqlState: '28000',
      fatal: true }
    error when connecting to db: { [Error: ER_ACCESS_DENIED_ERROR: Access denied for user 'nodejs'@'localhost' (using pass
    rd: YES)]
      code: 'ER_ACCESS_DENIED_ERROR',
      errno: 1045,
      sqlState: '28000',
      fatal: true }
    

    b. 模拟数据库宕机
    正常启动node,然后杀掉mysqld的进程。

    控制台输出。

    
    D:workspacejavascript
    odejs-node-mysql>node app-reconnect.js
    db error { [Error: read ECONNRESET]
      code: 'ECONNRESET',
      errno: 'ECONNRESET',
      syscall: 'read',
      fatal: true }
    
    Error: read ECONNRESET
        at errnoException (net.js:884:11)
        at TCP.onread (net.js:539:19)
    

    这个异常,直接导致node程序被杀死!

    c. 模拟连接超时,PROTOCOL_CONNECTION_LOST
    切换到root账户, 修改MySQL的wait_timeout参数,设置为10毫秒超时。

    ~ mysql -uroot -p
    mysql> show variables like 'wait_timeout';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | wait_timeout  | 28800 |
    +---------------+-------+
    1 row in set (0.00 sec)
    
    mysql> set global wait_timeout=10;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show variables like 'wait_timeout';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | wait_timeout  | 10    |
    +---------------+-------+
    1 row in set (0.00 sec)
    

    修改文件:app-reconnection.js,在最后增加代码

    ~ vi app-reconnection.js
    
    function query(){
        console.log(new Date());
        var sql = "show variables like 'wait_timeout'";
        conn.query(sql, function (err, res) {
            console.log(res);
        });
    }
    
    query();
    setInterval(query, 15*1000);
    

    程序会每融15秒,做一次查询。

    控制台输出

    D:workspacejavascript
    odejs-node-mysql>node app-reconnect.js
    Wed Sep 11 2013 15:21:14 GMT+0800 (中国标准时间)
    [ { Variable_name: 'wait_timeout', Value: '10' } ]
    db error { [Error: Connection lost: The server closed the connection.] fatal: true, code: 'PROTOCOL_CONNECTION_LOST' }
    Wed Sep 11 2013 15:21:28 GMT+0800 (中国标准时间)
    [ { Variable_name: 'wait_timeout', Value: '10' } ]
    db error { [Error: Connection lost: The server closed the connection.] fatal: true, code: 'PROTOCOL_CONNECTION_LOST' }
    Wed Sep 11 2013 15:21:43 GMT+0800 (中国标准时间)
    [ { Variable_name: 'wait_timeout', Value: '10' } ]
    

    我们自己的程序捕获了“PROTOCOL_CONNECTION_LOST”异常,并自动的实现了数据库重连。

    4). MySQL连接池的超时测试

    针对wait_timeout问题,我们再对连接做一下测试。

    修改app-pooling.js文件

    
    var mysql = require('mysql');
    var pool = mysql.createPool({
        host: 'localhost',
        user: 'nodejs',
        password: 'nodejs',
        database: 'nodejs',
        port: 3306
    });
    
    var selectSQL ="show variables like 'wait_timeout'";
    
    pool.getConnection(function (err, conn) {
        if (err) console.log("POOL ==> " + err);
    
        function query(){
            conn.query(selectSQL, function (err, res) {
                console.log(new Date());
                console.log(res);
                conn.release();
            });
        }
        query();
        setInterval(query, 5000);
    });
    

    控制台输出:

    D:workspacejavascript
    odejs-node-mysql>node app-pooling.js
    Wed Sep 11 2013 15:32:25 GMT+0800 (中国标准时间)
    [ { Variable_name: 'wait_timeout', Value: '10' } ]
    Wed Sep 11 2013 15:32:30 GMT+0800 (中国标准时间)
    [ { Variable_name: 'wait_timeout', Value: '10' } ]
    Wed Sep 11 2013 15:32:35 GMT+0800 (中国标准时间)
    [ { Variable_name: 'wait_timeout', Value: '10' } ]
    

    连接池,已经解决了自动重连的问题了,后面我们的开发,可以尽量使用pooling的方式。

  • 相关阅读:
    centos7.6 安装与配置 MongoDB yum方式
    MongoDB 介绍
    centos 关闭selinux
    前端 HTML标签属性
    前端 HTML 标签嵌套规则
    前端 HTML 标签分类
    前端 HTML body标签相关内容 常用标签 表单标签 form里面的 input标签介绍
    前端 HTML body标签相关内容 常用标签 表单标签 form 表单控件分类
    前端 HTML form表单标签 select标签 option 下拉框
    POJ 1426
  • 原文地址:https://www.cnblogs.com/wuye1200/p/5427688.html
Copyright © 2011-2022 走看看