初识NodeJS服务端开发入门(Express+MySQL)


Posted in NodeJs onApril 07, 2017

NodeJS对前端来说无疑具有里程碑意义,在其越来越流行的今天,掌握NodeJS已经不再是加分项,而是前端攻城师们必须要掌握的技能。本文将与同志们一起完成一个基于Express+MySQL的入门级服务端应用,即可以对数据库中的一张表进行简单的CRUD操作。但本人还是斗胆认为,通过这个应用,可以让没怎么接触后端开发的同志对使用Node进行后端开发有一个大致了解。

Express工程环境准备

1. 安装express,和express项目种子生成器(什么?你问第1步为什么不是安装NodeJS,我也只能呵呵..)

安装express

npm install express -g

安装express

npm install express-generator -g

2. 创建工程。进入工程目录,运行命令

express projectName

expresst项目种子生成器会帮我们生成express相应的工程结构,如下

初识NodeJS服务端开发入门(Express+MySQL)

/bin: 用于应用启动

/public: 静态资源目录

/routes:可以认为是controller(控制器)目录

/views: jade模板目录,可以认为是view(视图)目录

app.js 程序main文件

3. 进入工程,安装依赖,然后启动应用在工程根目录,使用npm install安装依赖,使用npm start启动应用。完成后,你在命令行工具里会看出如下界面,在浏览器中访问会得到我们应用的默认页面

初识NodeJS服务端开发入门(Express+MySQL)

初识NodeJS服务端开发入门(Express+MySQL)

MySQL环境准备

1. 当然,首先你要准备好MySQL环境。可以参看https://3water.com/article/39188.htm进行安装,同时也建议安装一个数据库管理工具,如navicat for mysql,方便操作

2. 创建表MySQL安装好了后,进入到数据库,创建要用到的表(如user), 结构如下

初识NodeJS服务端开发入门(Express+MySQL)

3. 安装Node的MySQL驱动(请允许装X一下…)在package.json的dependencies中新增, “mysql” : “latest”, 并执行npm install安装依赖

编写相关代码,整合Express+MySQL

1. 首先,我们先建几个目录,简单分下层(看出我还是很用心木有?)

在工程根目录新增三个目录:

util ? 工具方法

conf ? 配置

dao ? 与数据库交互

完成后的工程结构

初识NodeJS服务端开发入门(Express+MySQL)

2.在conf目录中,编写mySQL数据库连接配置

// conf/db.js
// MySQL数据库联接配置
module.exports = {
	mysql: {
		host: '127.0.0.1', 
		user: 'root',
		password: '',
		database:'test', // 前面建的user表位于这个数据库中
		port: 3306
	}
};

2. 编写CRUD SQL语句

// dao/userSqlMapping.js
// CRUD SQL语句
var user = {
	insert:'INSERT INTO user(id, name, age) VALUES(0,?,?)',
	update:'update user set name=?, age=? where id=?',
	delete: 'delete from user where id=?',
	queryById: 'select * from user where id=?',
	queryAll: 'select * from user'
};

module.exports = user;

3. 增加路由及实现数据库的CRUD

以C(新增)的具体实现举例,在/routes/users.js 中增加一个路由

// 增加用户
router.get('/addUser', function(req, res, next) {
	userDao.add(req, res, next);
});

在userDao中实现add方法

// dao/userDao.js
// 实现与MySQL交互
var mysql = require('mysql');
var $conf = require('../conf/conf');
var $util = require('../util/util');
var $sql = require('./userSqlMapping');

// 使用连接池,提升性能
var pool = mysql.createPool($util.extend({}, $conf.mysql));

// 向前台返回JSON方法的简单封装
var jsonWrite = function (res, ret) {
	if(typeof ret === 'undefined') {
		res.json({
			code:'1',
			msg: '操作失败'
		});
	} else {
		res.json(ret);
	}
};

module.exports = {
	add: function (req, res, next) {
		pool.getConnection(function(err, connection) {
			// 获取前台页面传过来的参数
			var param = req.query || req.params;

			// 建立连接,向表中插入值
			// 'INSERT INTO user(id, name, age) VALUES(0,?,?)',
			connection.query($sql.insert, [param.name, param.age], function(err, result) {
				if(result) {
					result = {
						code: 200,
						msg:'增加成功'
					}; 
				}

				// 以json形式,把操作结果返回给前台页面
				jsonWrite(res, result);

				// 释放连接 
				connection.release();
			});
		});
	}
};

4. 测试整合是否成功

因为前面实现的是一个get请求的add方法, 所以可以在浏览器中直接使用地址访问,进入路由, http://localhost:3000/users/addUser?name=xyz&age=18.如果你得到如下JSON返回或看到数据表中有上面的数据插入,表示整合成功了

初识NodeJS服务端开发入门(Express+MySQL)

初识NodeJS服务端开发入门(Express+MySQL)

5. 同理,实现CRUD其它的方法,最终完整的的routes/user.js为:

var express = require('express');
var router = express.Router();

var userDao = require('../dao/userDao');

/* GET users listing. */
router.get('/', function(req, res, next) {
 res.send('respond with a resource');
});

// 增加用户
//TODO 同时支持get,post
router.get('/addUser', function(req, res, next) {
	userDao.add(req, res, next);
});

router.get('/queryAll', function(req, res, next) {
	userDao.queryAll(req, res, next);
});

router.get('/query', function(req, res, next) {
	userDao.queryById(req, res, next);
});

router.get('/deleteUser', function(req, res, next) {
	userDao.delete(req, res, next);
});

router.post('/updateUser', function(req, res, next) {
	userDao.update(req, res, next);
});

module.exports = router;

完整的userDao.js为

// dao/userDao.js
// 实现与MySQL交互
var mysql = require('mysql');
var $conf = require('../conf/db');
var $util = require('../util/util');
var $sql = require('./userSqlMapping');

// 使用连接池,提升性能
var pool = mysql.createPool($util.extend({}, $conf.mysql));

// 向前台返回JSON方法的简单封装
var jsonWrite = function (res, ret) {
	if(typeof ret === 'undefined') {
		res.json({
			code:'1',
			msg: '操作失败'
		});
	} else {
		res.json(ret);
	}
};

module.exports = {
	add: function (req, res, next) {
		pool.getConnection(function(err, connection) {
			// 获取前台页面传过来的参数
			var param = req.query || req.params;

			// 建立连接,向表中插入值
			// 'INSERT INTO user(id, name, age) VALUES(0,?,?)',
			connection.query($sql.insert, [param.name, param.age], function(err, result) {
				if(result) {
					result = {
						code: 200,
						msg:'增加成功'
					}; 
				}

				// 以json形式,把操作结果返回给前台页面
				jsonWrite(res, result);

				// 释放连接 
				connection.release();
			});
		});
	},
	delete: function (req, res, next) {
		// delete by Id
		pool.getConnection(function(err, connection) {
			var id = +req.query.id;
			connection.query($sql.delete, id, function(err, result) {
				if(result.affectedRows > 0) {
					result = {
						code: 200,
						msg:'删除成功'
					};
				} else {
					result = void 0;
				}
				jsonWrite(res, result);
				connection.release();
			});
		});
	},
	update: function (req, res, next) {
		// update by id
		// 为了简单,要求同时传name和age两个参数
		var param = req.body;
		if(param.name == null || param.age == null || param.id == null) {
			jsonWrite(res, undefined);
			return;
		}

		pool.getConnection(function(err, connection) {
			connection.query($sql.update, [param.name, param.age, +param.id], function(err, result) {
				// 使用页面进行跳转提示
				if(result.affectedRows > 0) {
					res.render('suc', {
						result: result
					}); // 第二个参数可以直接在jade中使用
				} else {
					res.render('fail', {
						result: result
					});
				}

				connection.release();
			});
		});

	},
	queryById: function (req, res, next) {
		var id = +req.query.id; // 为了拼凑正确的sql语句,这里要转下整数
		pool.getConnection(function(err, connection) {
			connection.query($sql.queryById, id, function(err, result) {
				jsonWrite(res, result);
				connection.release();

			});
		});
	},
	queryAll: function (req, res, next) {
		pool.getConnection(function(err, connection) {
			connection.query($sql.queryAll, function(err, result) {
				jsonWrite(res, result);
				connection.release();
			});
		});
	}

};

除了update测试外,其它get请求都可以直接在浏览器中使用地址+参数完成测试。为了模拟post请求,同时简单使用下jade模板(Express支持的一种模板引擎),我们在/views目录新建三个jade文件

updateUser.jade

extends layout
block content
	h1 更新用户资料
	form(method='post', action='/p/users/updateUser')
		div.form-row
			label
				span ID:
				input(type='text',name='id')
		div.form-row
			label
				span name:
				input(type='text',name='name')
		div.form-row
			label
				span age:
				input(type='text',name='age')
		div.form-row
			input(type='submit')

suc.jade

block content
 h1 操作成功!
 pre #{JSON.stringify(result)}

fail.jade

block content
 h1 操作失败!
 pre #{JSON.stringify(result)}

以下是更新测试结果

初识NodeJS服务端开发入门(Express+MySQL)

最后,如果你使用的是idea或webStrom这样的IDE,你就不需要安装express和express项目种子生成器了。这两个IDE是可以直接创建NodeJS项目

初识NodeJS服务端开发入门(Express+MySQL)

初识NodeJS服务端开发入门(Express+MySQL)

初识NodeJS服务端开发入门(Express+MySQL)

初识NodeJS服务端开发入门(Express+MySQL)

小结:

一个Express的helloWorld就差不多完成了, 可以通过这个链接下载此例子源代码http://pan.baidu.com/s/1jGvd4Bc。更多Express的功能(如日志,自动化测试等),等待大家去解锁,愿玩得愉快!

NodeJs 相关文章推荐
nodejs调用cmd命令实现复制目录
May 04 NodeJs
简单实现nodejs上传功能
Jan 14 NodeJs
NodeJS配置HTTPS服务实例分享
Feb 19 NodeJs
详解nodejs操作mongodb数据库封装DB类
Apr 10 NodeJs
使用vs code开发Nodejs程序的使用方法
Sep 21 NodeJs
详解nodejs通过代理(proxy)发送http请求(request)
Sep 22 NodeJs
nodejs实现爬取网站图片功能
Dec 14 NodeJs
nodejs使用http模块发送get与post请求的方法示例
Jan 08 NodeJs
NodeJS实现不可逆加密与密码密文保存的方法
Mar 16 NodeJs
nodejs的路径问题的解决
Jun 30 NodeJs
nodejs 如何手动实现服务器
Aug 20 NodeJs
Nodejs中使用puppeteer控制浏览器中视频播放功能
Aug 26 NodeJs
nodejs服务搭建教程 nodejs访问本地站点文件
Apr 07 #NodeJs
nodejs爬虫遇到的乱码问题汇总
Apr 07 #NodeJs
详解nodejs爬虫程序解决gbk等中文编码问题
Apr 06 #NodeJs
NodeJS基础API搭建服务器详细过程记录
Apr 01 #NodeJs
Ajax异步文件上传与NodeJS express服务端处理
Apr 01 #NodeJs
3分钟快速搭建nodejs本地服务器方法运行测试html/js
Apr 01 #NodeJs
nodejs使用express创建一个简单web应用
Mar 31 #NodeJs
You might like
业余方法DIY电子管FM收音机
2021/03/02 无线电
PHP安全防范技巧分享
2011/11/03 PHP
php不用正则验证真假身份证
2013/11/06 PHP
PHP基于phpqrcode类生成二维码的方法详解
2018/03/14 PHP
让iframe框架网页在任何浏览器下自动伸缩
2006/08/18 Javascript
JSQL 批量图片切换的实现代码
2010/05/05 Javascript
php上传图片并给图片打上透明水印的代码
2010/06/07 Javascript
JavaScript操作XML 使用百度RSS作为新闻源示例
2012/02/17 Javascript
Javascript的各种节点操作实例演示代码
2012/06/27 Javascript
js 三级关联菜单效果实例
2013/08/13 Javascript
jQuery鼠标事件汇总
2015/08/30 Javascript
基于jQuery仿淘宝产品图片放大镜特效
2020/10/19 Javascript
JQuery对ASP.NET MVC数据进行更新删除
2016/07/13 Javascript
JS在Chrome浏览器中showModalDialog函数返回值为undefined的解决方法
2016/08/03 Javascript
ionic实现可滑动的tab选项卡切换效果
2020/04/15 Javascript
jQuery实现的超链接提示效果示例【附demo源码下载】
2016/09/09 Javascript
JavaScript获取ul中li个数的方法
2017/02/13 Javascript
layui导航栏实现代码
2017/05/19 Javascript
基于javaScript的this指向总结
2017/07/22 Javascript
vue中使用protobuf的过程记录
2018/10/26 Javascript
使用jquery-easyui的布局layout写后台管理页面的代码详解
2019/06/19 jQuery
详解js创建对象的几种方式和对象方法
2021/03/01 Javascript
python通过shutil实现快速文件复制的方法
2015/03/14 Python
在Gnumeric下使用Python脚本操作表格的教程
2015/04/14 Python
Python 快速实现CLI 应用程序的脚手架
2017/12/05 Python
利用python实现冒泡排序算法实例代码
2019/12/01 Python
python实现从wind导入数据
2019/12/03 Python
印度婴儿用品在线商店:Firstcry.com
2016/12/05 全球购物
英国领先的品牌珠宝和配件供应商:Acotis Jewellery
2018/03/07 全球购物
英国PC组件和在线电脑商店:SCAN
2019/04/18 全球购物
俄罗斯厨房产品购物网站:COOK HOUSE
2021/03/15 全球购物
幼儿园托班开学寄语
2014/01/18 职场文书
学习两会精神心得范文
2014/03/17 职场文书
中学教师暑期培训方案
2014/08/27 职场文书
晚会闭幕词
2015/01/28 职场文书
悬疑名作《朋友游戏》动画无字ED宣传片 新角色公开
2022/04/13 日漫