NodeJS對前端來講無疑具備里程碑意義,在其愈來愈流行的今天,掌握NodeJS已經再也不是加分項,而是前端攻城師們必需要掌握的技能。本文將與同志們一塊兒完成一個基於Express+MySQL的入門級服務端應用,便可以對數據庫中的一張表進行簡單的CRUD操做。但本人仍是斗膽認爲,經過這個應用,可讓沒怎麼接觸後端開發的同志對使用Node進行後端開發有一個大體瞭解。前端
Express工程環境準備mysql
安裝expressweb
npm install express -g
安裝expresssql
npm install express-generator -g
建立工程。進入工程目錄,運行命令數據庫
express projectName
expresst項目種子生成器會幫咱們生成express相應的工程結構,以下express
在工程根目錄,使用npm install安裝依賴,使用npm start啓動應用。完成後,你在命令行工具裏會看出以下界面,在瀏覽器中訪問會獲得咱們應用的默認頁面npm
MySQL環境準備json
固然,首先你要準備好MySQL環境。能夠參看http://supportopensource.iteye.com/blog/1415527進行安裝,同時也建議安裝一個數據庫管理工具,如navicat for mysql,方便操做後端
建立表瀏覽器
MySQL安裝好了後,進入到數據庫,建立要用到的表(如user), 結構以下
在package.json的dependencies中新增, 「mysql」 : 「latest」, 並執行npm install安裝依賴
編寫相關代碼,整合Express+MySQL
在工程根目錄新增三個目錄:
util – 工具方法
conf – 配置
dao – 與數據庫交互
完成後的工程結構
2.在conf目錄中,編寫mySQL數據庫鏈接配置
// conf/db.js // MySQL數據庫聯接配置 module.exports = { mysql: { host: '127.0.0.1', user: 'root', password: '', database:'test', // 前面建的user表位於這個數據庫中 port: 3306 } };
編寫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;
增長路由及實現數據庫的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(); }); }); } };
由於前面實現的是一個get請求的add方法, 因此能夠在瀏覽器中直接使用地址訪問,進入路由, http://localhost:3000/users/addUser?name=xyz&age=18.若是你獲得以下JSON返回或看到數據表中有上面的數據插入,表示整合成功了
同理,實現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)}
如下是更新測試結果
最後,若是你使用的是idea或webStrom這樣的IDE,你就不須要安裝express和express項目種子生成器了。這兩個IDE是能夠直接建立NodeJS項目
小結:
一個Express的helloWorld就差很少完成了, 能夠經過這個連接下載此例子源代碼http://pan.baidu.com/s/1jGvd4Bc。更多Express的功能(如日誌,自動化測試等),等待你們去解鎖,願玩得愉快!