• 用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的方式。

  • 相关阅读:
    H5版俄罗斯方块(5)---需求演进和产品迭代
    vim 常用 NERDTree 快捷键
    C和C++中include 搜索路径的一般形式以及gcc搜索头文件的路径
    MySQL复制协议
    深入解析MySQL replication协议
    Install CodeBlocks in CentOS 7
    Impala 源码分析-FE
    Elasticsearch 6.x 的分页查询数据
    1、树莓派3B开箱+安装系统
    Python创建ES索引
  • 原文地址:https://www.cnblogs.com/wuye1200/p/5427688.html
Copyright © 2020-2023  润新知