node.js和MySQL

   这篇文档主要是总结Node.jsMysql的学习心得体会。当然也可以看作是此前所写的消息推送服务的续篇。

         简单描述下应用背景,我们的应用需要实现苹果的消息推送服务APNs,之前已经实现了iOS客户端配置和功能代码,也实现了推送通知的本地Provider功能代码,具体参考此前的系列总结。好比一个三角形,A点代表iOS移动设备端,B点代表苹果的消息推送服务器,C点代表应用开发者的本地服务器,现在AB连接好了,BC也连接好了,就差A

B建立连接沟通。

         这样一来,很明显就是要在本地搭建一个服务器了,可以处理A发送的请求;当然也少不了数据库,用来存储相关数据。

         说到这里,不同技术背景的人会有不同的方案,在此我采用了Node.js+Mysql的解决方案。当然其他方案如ASN.NETJSPPHP加上SQLServerMysqlMongoDB等等就不谈论了。纯粹作为技术学习和新方案的尝试。

         Node.js

         作为这篇文档的重点内容,Node.js肯定是要优先总结的。

         我这种刚学习Node.js的新手,就不敢把此文当做Node.js的入门资料了,只是简单介绍一下,然后直接根据应用需求实现代码。

       Node.js实现了服务端Javascript,通过简单快捷的环境搭建,就可以实现一个运行Javascript的服务器。

1  去官网下载最新的Node.js安装程序。说明一下,我是在Windows32位操作系统上安装,所以下载Windows对应安装程序即可。我的版本为:node-v0.10.24-x86

2  安装Node.js

3  在开始—>所有程序中,找到Node.js的命令行程序Node.js command prompt并运行

好了,至此,你已经可以开始编程了。就是这么简单快捷。

或许很多人还是很困惑,那在哪里写代码呢,命令行?

在此,我要说一下刚接触时候我的感受:我觉得很郁闷,不知道从何入手。

对于很多新手,大家需要的是把事情说明白一点,而不是玄乎。可以这样理解,Node.js就是一个服务器,用于搭载JavascriptCSSHtml等网页所可以有的一切。但是他本身不集成IDE。再具体点,他的出现,使我们可以不用熟悉的IISApacheTomcat来部署了,只需要运行Node.js,然后通过一句话“node xxx.js”,加载已经写好的Javascript,就一切OK了。是的,Javascript,那用你熟悉的任何方式和工具去书写吧。Notepad++是我选择的工具。

一定还有疑惑,没关系,我们先来看实例。

下列实例实现一个可以上传图片文件并预览的页面,还有一个向数据库插入一条数据的请求。

先看这个例子NodejsDemo的文件夹

说明:index.js是入口,server.js用于启动服务,router.js用于路由请求,requesHandlers.js用于处理路由后的对应请求,mysqlOperation.js用于处理数据库操作,mysqlDBHelper.js用于连接数据库并操作

接下就是具体代码部分了,太多语法我无法一下说清楚,在需要的地方,我会稍加说明,想了解更多,建议去官网查看API说明,毕竟是抛砖引玉哈。

              Index.js的代码:

 1 var server = require("./server");

 2

 3 var router = require("./router");

 4

 5 var requestHandlers = require("./requestHandlers");

 6 www.qqtop2.com

 7 

 8

 9 var handle = {}

10

11 handle["/"] = requestHandlers.start;

12

13 handle["/start"] = requestHandlers.start;

14

15 handle["/upload"] = requestHandlers.upload;

16

17 handle["/show"] = requestHandlers.show;

18

19 handle["/sendMyInfo"] = requestHandlers.sendMyInfo;

20

21 

22

23 server.start(router.route, handle);

View Code

说明:这是示例的入口,最后一句,调用server中的start方法,并传递两个参数,第一个是routerroute函数,第二个是类似字典实例的handle

      server.js的代码:

 1 var http = require('http');

 2

 3 var url = require('url');

 4

 5 function start(route, handle){

 6

 7               function onRequest(req,res){

 8

 9                        var pathname = url.parse(req.url).pathname;

10

11                        console.log("Request for " + pathname + " received.");

12

13                      

14

15                        route(handle, pathname, res,req);        

16

17               }

18

19               http.createServer(onRequest).listen(1337, 'Your IP');

20

21               console.log('Server running at http://Your IP:1337/');

22

23 }

24

25 

26

27 exports.start = start;

View Code

说明:与require(“./server”)调用同级目录js文件不同,require(‘http’)是生成一个http对象实例的方法。url.parse(string).pathname用于获取url字符串中路径名称。Your IP为本机的IP地址。http.createServer(function).listen(端口号,’IP’)用于通过一个方法创建一个服务,并在设置的iP和端口号监听。Exports.start=start为其他js对象调用本方法暴露接口。

 

route.js的代码

 1 function route(handle, pathname, res, req){

 2

 3               console.log("About to route a request for " + pathname);

 4               http://mingzi.78name.com

 5               if(typeof handle[pathname] === 'function'){

 6

 7                        handle[pathname](res, req);

 8

 9               }else{

10

11                        console.log("No request handler found for " + pathname);

12

13                        res.writeHead(404, {'Content-Type': 'text/plain'});

14

15                        res.end('404 route not found');

16

17               }

18

19 }

20

21 

22

23 exports.route = route;

View Code

说明:路由请求,当请求未定义的路径时,则在responsehead里面返回404错误。

requestHanlders.js的代码:

  1 var querystring = require ("querystring");

  2

  3 var url = require('url');

  4

  5 var fs = require("fs");

  6

  7 var formidable = require("formidable");

  8

  9 var util = require("util");

 10

 11 var mysqlOperation = require("./mysqlOperation");

 12

 13 var testPicPath = "/testPic/test.png";

 14

 15 function start(res, req){

 16

 17               console.log("Request handler 'start' was called.");

 18

 19               var body = '<html>'+

 20

 21                        '<head>'+

 22

 23                        '<meta http-equiv="Content-Type" content="text/html; '+

 24

 25                        'charset=UTF-8" />'+

 26

 27                        '</head>'+

 28

 29                        '<body>'+

 30

 31                        '<form action="/upload" enctype="multipart/form-data" method="post">'+

 32

 33                        '<input type="file" name="upload">'+

 34

 35                        '<input type="submit" value="Upload file" />'+

 36

 37                        '</form>'+

 38

 39                        '</body>'+

 40

 41                        '</html>';

 42

 43               res.writeHead(200, {'Content-Type': 'text/html'});

 44

 45               res.end(body);

 46

 47 }

 48

 49 

 50

 51 function upload(res, req){

 52

 53               console.log("Request handler 'upload' was called.");

 54

 55 

 56

 57               var form = new formidable.IncomingForm();

 58

 59 

 60

 61               console.log("about to parse");

 62

 63 

 64

 65               form.parse (req, function(error, fields, files) {

 66

 67                        console.log("parsing done");

 68

 69 /*                  res.writeHead(200,{"Content-type":"text/plain"});

 70

 71                        res.write("received upload:\n\n");

 72

 73                        res.write(util.inspect({fields:fields,files:files})); */

 74

 75 

 76

 77                        fs.rename(files.upload.path, '/testPic/' + files.upload.name, function(err){

 78

 79                                  if(err) throw err;

 80

 81                                  console.log("renamed complete");

 82

 83                                  testPicPath =  "/testPic/" + files.upload.name;

 84

 85                                

 86

 87                                  res.writeHead (200, {"Content-Type": "text/html"});

 88

 89 

 90

 91                                  res.write ("received image:<br/>");

 92

 93 

 94

 95                                  res.write ("<img src= '/show' />");

 96

 97 

 98

 99                                  res.end();

100

101                        });

102

103               });

104

105 }

106

107 

108

109 function show(res, req) {

110

111               console.log("Request handler 'show' was called.");

112

113               fs.readFile (testPicPath, "binary", function(error, file) {

114

115                        if(error) {

116

117                                  res.writeHead (500, {"Content-Type": "text/plain"});

118

119                                  res.write ("Image error: " + error + "\n");

120

121                                  res.end();

122

123                        } else {

124

125                                  res.writeHead (200, {"Content-Type": "image/png"});

126

127                                  res.write (file, "binary");

128

129                                  res.end();

130

131                        }

132

133               });

134

135 }

136

137 

138

139 function sendMyInfo(res,req){

140

141               console.log("Request handler 'sendMyInfo' was called.");

142

143               var urlstring = url.parse(req.url).query;

144

145               var user = {

146

147                        name : querystring.parse(urlstring).name,

148

149                        country : querystring.parse(urlstring).country,

150

151                        city : querystring.parse(urlstring).city,

152

153                        street : querystring.parse(urlstring).street

154

155               };

156

157             

158

159               if(use.name == undefined || user.country == undefined

160

161 || user.city == undefined || user.street == undefined){

162

163                        res.writeHead (500, {"Content-Type": "text/plain"});

164

165                        res.write ("error: paras undefined.");

166

167                        res.end();

168

169                        console.log("error: paras undefined.");

170

171                        return;

172

173               }

174

175             

176

177               console.log(user);

178

179               mysqlOperation.storeUserInfo(user,res);

180

181 }

182

183 

184

185 exports.start = start;

186

187 exports.upload = upload;

188

189 exports.show = show;

190

191 exports.sendMyInfo = sendMyInfo;

View Code

说明:这个js文件是处理请求的主要地方,当路由路径后,会找到相应方法。

这里需要重点说一下start方法。在返回response内容时候,直接采用字符串方式表达body,当然这是不好的习惯,那么在疑惑页面的朋友就可以在这里找到答案了。Node.js有负责加载页面的API,还有类似于模板页的结构,以前熟悉的方式依然可以使用。至于其他方法,相信你会看明白的。还有,为什么错误返回码总是500呢,因为是我随意设置的。。。

         至此,一个简单的Node.jsdemo就完成了,噢,忘了方法sendMyInfo,那是等下继续要说的。马上运行Node.js的命令行程序,然后在路径>”后面输入“node index.js路径,回车就可以看到Server running的输出提示了。在浏览器里面访问“Your IPYour port/”

多说一句,index.js的全路径是绝对无误的,当index.js处于用户根目录时,可以直接输入“node index.js”;当index.js处于node.js的安装磁盘根目录时候,可以直接输入“node /index.js”

         在方法sendMyInfo中,我试图向数据库中插入一条记录。那就接着进入node.js的数据库连接和操作吧。

         Node.js的数据库操作之创建数据库

我们可以先在Mysql数据库里面创建好一个新的database和一个用户表users。也可以通过Node.js来创建,代码如下:

  1 var mysql = require('mysql');

  2

  3 var db_options = {

  4

  5     host: "localhost",

  6

  7     port: 3306,

  8

  9     user: "root",

 10

 11     password: "Your password"

 12

 13 };

 14

 15 var client = new mysql.createConnection(db_options);

 16

 17 

 18

 19 //要创建的数据库名

 20

 21 var TEST_DATABASE = 'NodeJsTest',

 22

 23     //要创建的表名

 24

 25     TEST_TABLE = Users;

 26

 27 

 28

 29 client.query('show databases', function(err, rows, fields){

 30

 31          if(err){

 32

 33                    console.log(err);

 34

 35          }else{

 36

 37                    console.log(rows);

 38

 39          }

 40

 41 });

 42

 43 

 44

 45 client.query('CREATE DATABASE '+TEST_DATABASE, function(err) {

 46

 47   if (err && err.number != client.ERROR_DB_CREATE_EXISTS) {

 48

 49     throw err;

 50

 51   }

 52

 53 });

 54

 55 

 56

 57 // If no callback is provided, any errors will be emitted as `'error'`

 58

 59 // events by the client

 60

 61 client.query('USE '+TEST_DATABASE);

 62

 63 client.query(

 64

 65   'CREATE TABLE '+TEST_TABLE+

 66

 67   ‘name VARCHAR(255), '+

 68

 69   ' country VARCHAR(255),'+

 70

 71   ' city VARCHAR(255), '+

 72

 73   ' street VARCHAR(255),'

 74

 75 );

 76

 77 

 78

 79 client.query(

 80

 81   'INSERT INTO '+TEST_TABLE+' '+

 82

 83   'SET name = ?, country = ?, city = ?, street = ?',

 84

 85   ['Li Lei', 'China', 'Bei jing', ‘ ’]

 86

 87 );

 88

 89 

 90

 91 client.query('USE '+TEST_DATABASE);

 92

 93 client.query(

 94

 95   'SELECT * FROM '+TEST_TABLE,

 96

 97   function selectCb(err, results, fields) {

 98

 99     if (err) {

100

101       throw err;

102

103     }

104

105 

106

107     console.log(results);

108

109          console.log(results[0].name);

110

111          console.log(results.length);   

112

113     console.log(fields); 

114

115   }

116

117 );

118

119 

120

121 client.end()

View Code

说明:Your password为你的Mysql数据库密码。好了,可以将代码所在的js文件直接加载到命令行中,方法还是“node xxxx.js”。如果你之前已经在运行index.js了,那么按下crtrl+C停下之前的服务。我想运行结果会成功的,除非node.jsAPI又升级了,这个时候就去查官网API吧。

         Node.js的数据库操作之插入数据

  1 var mysql = require('mysql');

  2

  3 var db_options = {

  4

  5     host: "localhost",

  6

  7     port: 3306,

  8

  9     user: "root",

 10

 11     password: "Your password"

 12

 13 };

 14

 15 

 16

 17 //database name

 18

 19 var DATABASE = ‘NodeJsTest’,

 20

 21 //table name

 22

 23 TABLE = 'Users';

 24

 25 function storeUserInfo(user, res){

 26

 27          if(user.name == " "){

 28

 29                    res.writeHead (600, {"Content-Type": "text/plain"});

 30

 31                    res.write ("error: name can not be empty.\n");

 32

 33                    res.end();

 34

 35                    return;

 36

 37          }

 38

 39          var client = new mysql.createConnection(db_options);

 40

 41          client.query('USE '+DATABASE);

 42

 43        

 44

 45          client.query(

 46

 47                    "SELECT * FROM "+ TABLE + " WHERE name = ?",

 48

 49                    [user.name],

 50

 51                    function(err, results, fields) {

 52

 53                             if (err) {

 54

 55                                      client.end();

 56

 57                                      res.writeHead (700, {"Content-Type": "text/plain"});

 58

 59                                      res.write ("error: " + err);

 60

 61                                      res.end();

 62

 63                                      return;

 64

 65                             }

 66

 67                           

 68

 69                             console.log(results.length);

 70

 71                             if(results.length < 1){

 72

 73                                      //Added new record

 74

 75                                      client.query(

 76

 77 "INSERT INTO "+ TABLE + " SET name = ?, country = ?, city = ?, street = ? ", [user.name, user.country, user.city, user.street],

 78

 79                                                function(err, results, fields) {

 80

 81                                                         if (err) {

 82

 83                                                                  client.end();

 84

 85                                                                  res.writeHead (700, {"Content-Type": "text/plain"});

 86

 87                                                                  res.write ("error: " + err);

 88

 89                                                                  res.end();

 90

 91                                                                  return;

 92

 93                                                         }                         

 94

 95                                                        

 96

 97                                                         client.end();

 98

 99                                                         res.writeHead (200, {"Content-Type": "text/plain"});

100

101                                                         res.write ("added new user");

102

103                                                         res.end();

104

105                                                         console.log(results);

106

107                                                         console.log(fields); 

108

109                                                }

110

111                                      );

112

113                             }else if(results.length == 1){

114

115                                      //Update record

116

117                                      client.query(

118

119 "UPDATE " + TABLE + " SET name = ?, country = ?, city = ?, street = ? WHERE name = ?", [user.name],

120

121                                                function(err, results, fields) {

122

123                                                         if (err) {

124

125                                                                  client.end();

126

127                                                                  res.writeHead (700, {"Content-Type": "text/plain"});

128

129                                                                  res.write ("error: " + err);

130

131                                                                  res.end();                                                                

132

133                                                                  return;

134

135                                                         }                         

136

137                                                        

138

139                                                         client.end();

140

141                                                         res.writeHead (200, {"Content-Type": "text/plain"});

142

143                                                         res.write ("updated");

144

145                                                         res.end();

146

147                                                         console.log(results);

148

149                                                         console.log(fields); 

150

151                                                }

152

153                                      )

154

155                             }else{

156

157                                      client.end();

158

159                                      res.writeHead (700, {"Content-Type": "text/plain"});

160

161                                      res.write ("error: Repeat records exist!");

162

163                                      res.end();

164

165                                      console.log("Repeat records exist!");

166

167                                      //handle

168

169                             } 

170

171                    }

172

173          );

174

175 }

176

177 

178

179 exports.storeUserInfo = storeUserInfo;

View Code

说明:这个js实现向数据库里面插入一条记录,如果已存在该用户,则更新用户信息。就是这样的熟悉味道。

忘了一点,我没有封装这个demo的数据库连接,因为当操作多了以后,还是封装一个负责数据库连接操作的DBHelper比较好。

 

到此,Node.js的总结就结束了,别忘了重新node index.js后,在浏览器里面访问“Your IP : Your port/sendMyInfo?name=xxx&country=xxx&city=xxx&street=xxx”

 

 

你可能感兴趣的:(node.js和MySQL)