新手帮助当前位置:万彩娱乐平台 > 新手帮助 > >

通过node-mysql搭建Windows+Node.js+MySQL环境的教程

  

[Windows,Node,js,MySQL,JavaScript]通过node-mysql搭建Windows+Node.js+MySQL环境的教程

  

前言  

  

MySQL是一款常用的开源数据库产品,通常也是免费数据库的首选。查了一下NPM列表,发现Nodejs有13库可以访问MySQL,felixge/node-mysql似乎是最受关注项目,我也决定尝试用一下。

  

  

要注意名字,”felixge/node-mysql”非”node-mysql”,安装部分会介绍这个小插曲!

  

  

目录  

  
      
  • node-mysql介绍
  •   
  • 建立MySQL测试库
  •   
  • node-mysql安装
  •   
  • node-mysql使用
  •   
  

1. node-mysql介绍  

  

felixge/node-mysql是一个纯nodejs的用javascript实现的一个MySQL客户端程序。felixge/node-mysql封装了Nodejs对MySQL的基本操作,100% MIT公共许可证。

  

  

项目地址:  

  

2. 建立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 [email protected]'%' IDENTIFIED BY 'nodejs';  mysql> GRANT ALL ON nodejs.* to [email protected] IDENTIFIED BY 'nodejs';  
  
  

重新登陆MySQL  

  
  
  C:\Users\Administrator>mysql -unodejs -p  Enter password: ******  mysql> SHOW DATABASES;  +--------------------+  | Database      |  +--------------------+  | information_schema |  | nodejs       |  | test        |  +--------------------+  3 rows in set (0.00 sec)  
  
  

  
  

  
  
  mysql> USE nodejs  Database changed  
  
  

新建一个user表  

  
  
  CREATE TABLE t_user(  id INT PRIMARY KEY AUTO_INCREMENT,  name VARCHAR(16) NOT NULL ,  create_date TIMESTAMP NULL DEFAULT now()  )ENGINE=InnoDB DEFAULT CHARSET=utf8;  CREATE UNIQUE INDEX t_quiz_IDX_0 on t_user(name);  
  
  

  
  

  
  
  mysql> SHOW TABLES;  +------------------+  | Tables_in_nodejs |  +------------------+  | t_user      |  +------------------+  1 row in set (0.04 sec)  
  
  

3. node-mysql安装  

  

我的系统环境  

  

win7 64bit  
  Nodejs:v0.10.5  
  Npm:1.2.19  
  MySQL:Server version: 5.6.11 MySQL Community Server (GPL)  
  创建工程:nodejs-node-mysql  

  
  
  ~ D:\workspace\javascript>mkdir nodejs-node-mysql  ~ D:\workspace\javascript>cd nodejs-node-mysql  ~ D:\workspace\javascript\nodejs-node-mysql>npm install node-mysql  node_modules\node-mysql  ├──  ├──  ├──  └──  (, )  
  
  

这里有一个小插曲  

  

安装“node-mysql”后,打开package.json文件发现,这个项目地址是  

  

  
  从依赖关系可以看到,它依赖于mysql库,是对felixge/node-mysql的封装。

  

  

node-mysql1  

  

由于这个项目star是0,fork也是0. 所以,我也不准备花时间测试了,重新安装felixge/node-mysql的包。

  

  

重新安装node-mysql  

  
  
  ~ D:\workspace\javascript\nodejs-node-mysql>rm -rf node_modules  ~ D:\workspace\javascript\nodejs-node-mysql>npm install  npm http GET  npm http 200  npm http GET  npm http 200  npm http GET  npm http GET  npm http 304  npm http 304  node_modules\mysql  ├──  └──  
  
  

这回就对了,继续下面的开发!

  

  

创建node程序启动文件: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();  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  

  
  
  ~ D:\workspace\javascript\nodejs-node-mysql>node app.js  The solution is: 2  
  
  

这样我们就让Nodejs连接上了MySQL。

  

  

4. 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:\workspace\javascript\nodejs-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:\workspace\javascript\nodejs-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种错误  

  

a.登陆密码错误  
  b.数据库宕机  
  c.数据库连接超时  
  新增文件: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:\workspace\javascript\nodejs-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:\workspace\javascript\nodejs-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:\workspace\javascript\nodejs-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:\workspace\javascript\nodejs-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的方式。

  

(责任编辑:admin)

上一篇:微信小程序(应用号)开发新闻客户端实例

下一篇:没有了

推荐内容

客户服务热线

010-400-12345

在线客服