├── views ├── error.jade ├── layout.jade └── index.jade ├── public └── stylesheets │ └── style.css ├── conf └── db.js ├── routes ├── users.js └── index.js ├── good ├── goodsql.js └── goodlist.js ├── util └── util.js ├── package.json ├── app.js ├── express.sql ├── bin └── www └── README.md /views/error.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | a { 7 | color: #00B7FF; 8 | } 9 | -------------------------------------------------------------------------------- /views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | link(rel='stylesheet', href='/stylesheets/style.css') 6 | body 7 | block content 8 | -------------------------------------------------------------------------------- /conf/db.js: -------------------------------------------------------------------------------- 1 | // conf/db.js 2 | // MySQL数据库联接配置 3 | module.exports = { 4 | mysql: { 5 | host: 'localhost', 6 | user: 'root', 7 | password: 'root', 8 | database:'test', // 前面建的user表位于些数据库中 9 | port: 3306 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | //这个路由可以设置用户 5 | /* GET users listing. */ 6 | router.get('/', function(req, res, next) { 7 | res.send('respond with a resource'); 8 | }); 9 | 10 | 11 | module.exports = router; 12 | -------------------------------------------------------------------------------- /good/goodsql.js: -------------------------------------------------------------------------------- 1 | var good={ 2 | //增 3 | goodinsert:'INSERT INTO `good` (`id`,`name`,`desc`,`price`,`sum`) VALUES(0,?,?,?,?)', 4 | //删 5 | gooddelete: 'delete from good where id=?', 6 | //改 7 | goodupdate:'UPDATE `good` SET `name`=?,`desc`=?,`price`=?,`sum`=? WHERE `id`=?', 8 | //查 9 | goodAll: 'select * from good', 10 | goodById: 'select * from good where id=?' 11 | } 12 | 13 | module.exports=good; -------------------------------------------------------------------------------- /util/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by fujunou on 2015/3/6. 3 | */ 4 | 5 | module.exports = { 6 | extend: function(target, source, flag) { 7 | for(var key in source) { 8 | if(source.hasOwnProperty(key)) 9 | flag ? 10 | (target[key] = source[key]) : 11 | (target[key] === void 0 && (target[key] = source[key])); 12 | } 13 | return target; 14 | } 15 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "projectName", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.15.1", 10 | "cookie-parser": "~1.4.3", 11 | "debug": "~2.2.0", 12 | "express": "~4.13.4", 13 | "jade": "~1.11.0", 14 | "morgan": "~1.7.0", 15 | "serve-favicon": "~2.3.0" 16 | }, 17 | "devDependencies": { 18 | "mysql": "^2.11.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /views/index.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= title 5 | p #{title} nodejs服务api接口说明 6 | li 通过id查询: 7 | a(href="http://localhost:3000/goodDel?id=115") http://localhost:3000/goodDel?id=115 8 | 9 | li 添加商品: 10 | a(href="http://localhost:3000/goodAdd?name=567&desc=全世界最好吃的苹果&price=12.00&sum=23") http://localhost:3000/goodAdd?name=567&desc=全世界最好吃的苹果&price=12.00&sum=23 11 | 12 | li 通过id修改商品: 13 | a(href="http://localhost:3000/goodUpdate?name=苹果&desc=【北京特产】送礼必备,赶紧抢购吧!&price=45.00&sum=12&id=1") http://localhost:3000/goodUpdate?name=苹果&desc=【北京特产】送礼必备,赶紧抢购吧!&price=45.00&sum=12&id=1 14 | 15 | li 查询所有商品: 16 | a(href="http://localhost:3000/goodAll ") http://localhost:3000/goodAll 17 | 18 | li 查询单个商品: 19 | a(href="http://localhost:3000/goodById?id=112") http://localhost:3000/goodById?id=112 -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | //关联主程序 4 | var goodlist = require('../good/goodlist.js'); 5 | 6 | /* GET home page. */ 7 | //进入主页面信息 8 | router.get('/', function(req, res, next) { 9 | res.render('index', { title: '小k博客 (htmlk.cn)'}); 10 | }); 11 | 12 | //增 13 | router.get('/goodAdd',function(req,res,next){ 14 | goodlist.goodadd(req,res,next); 15 | }); 16 | 17 | //删 18 | router.get('/goodDel',function(req,res,next){ 19 | goodlist.gooddelete(req,res,next); 20 | }); 21 | //改 22 | router.get('/goodUpdate',function(req,res,next){ 23 | goodlist.goodupdate(req,res,next); 24 | }); 25 | //查 26 | router.get('/goodAll',function(req,res,next){ 27 | goodlist.goodAll(req,res,next); 28 | }); 29 | router.get('/goodById',function(req,res,next){ 30 | goodlist.goodById(req,res,next); 31 | }); 32 | 33 | module.exports = router; 34 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var path = require('path'); 3 | var favicon = require('serve-favicon'); 4 | var logger = require('morgan'); 5 | var cookieParser = require('cookie-parser'); 6 | var bodyParser = require('body-parser'); 7 | 8 | var routes = require('./routes/index'); 9 | var users = require('./routes/users'); 10 | 11 | var app = express(); 12 | 13 | // view engine setup 14 | app.set('views', path.join(__dirname, 'views')); 15 | app.set('view engine', 'jade'); 16 | 17 | // uncomment after placing your favicon in /public 18 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 19 | app.use(logger('dev')); 20 | app.use(bodyParser.json()); 21 | app.use(bodyParser.urlencoded({ extended: false })); 22 | app.use(cookieParser()); 23 | app.use(express.static(path.join(__dirname, 'public'))); 24 | 25 | //设置路由 26 | app.use('/', routes); 27 | app.use('/users', users); 28 | 29 | // catch 404 and forward to error handler 30 | app.use(function(req, res, next) { 31 | var err = new Error('Not Found'); 32 | err.status = 404; 33 | next(err); 34 | }); 35 | 36 | // error handlers 37 | 38 | // development error handler 39 | // will print stacktrace 40 | if (app.get('env') === 'development') { 41 | app.use(function(err, req, res, next) { 42 | res.status(err.status || 500); 43 | res.render('error', { 44 | message: err.message, 45 | error: err 46 | }); 47 | }); 48 | } 49 | 50 | // production error handler 51 | // no stacktraces leaked to user 52 | app.use(function(err, req, res, next) { 53 | res.status(err.status || 500); 54 | res.render('error', { 55 | message: err.message, 56 | error: {} 57 | }); 58 | }); 59 | 60 | 61 | module.exports = app; 62 | -------------------------------------------------------------------------------- /express.sql: -------------------------------------------------------------------------------- 1 | /* 2 | SQLyog 企业版 - MySQL GUI v8.14 3 | MySQL - 5.5.40 : Database - test 4 | ********************************************************************* 5 | */ 6 | 7 | /*!40101 SET NAMES utf8 */; 8 | 9 | /*!40101 SET SQL_MODE=''*/; 10 | 11 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 12 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 13 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 14 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 15 | CREATE DATABASE /*!32312 IF NOT EXISTS*/`test` /*!40100 DEFAULT CHARACTER SET utf8 */; 16 | 17 | USE `test`; 18 | 19 | /*Table structure for table `good` */ 20 | 21 | DROP TABLE IF EXISTS `good`; 22 | 23 | CREATE TABLE `good` ( 24 | `id` int(20) NOT NULL AUTO_INCREMENT, 25 | `name` varchar(255) DEFAULT NULL, 26 | `desc` varchar(255) DEFAULT NULL, 27 | `price` int(20) DEFAULT NULL, 28 | `sum` int(20) DEFAULT NULL, 29 | PRIMARY KEY (`id`) 30 | ) ENGINE=MyISAM AUTO_INCREMENT=120 DEFAULT CHARSET=utf8; 31 | 32 | /*Data for the table `good` */ 33 | 34 | insert into `good`(`id`,`name`,`desc`,`price`,`sum`) values (119,'567','全世界最好吃的苹果',12,115),(118,'567','全世界最好吃的苹果',12,23); 35 | 36 | /*Table structure for table `user` */ 37 | 38 | DROP TABLE IF EXISTS `user`; 39 | 40 | CREATE TABLE `user` ( 41 | `id` int(20) DEFAULT NULL, 42 | `name` char(255) DEFAULT NULL, 43 | `age` char(255) DEFAULT NULL 44 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; 45 | 46 | /*Data for the table `user` */ 47 | 48 | insert into `user`(`id`,`name`,`age`) values (0,'23','23'),(0,'21233','23'); 49 | 50 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 51 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 52 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 53 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 54 | -------------------------------------------------------------------------------- /bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('projectName:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /good/goodlist.js: -------------------------------------------------------------------------------- 1 | //实现与mysql交互 2 | var mysql=require('mysql'); 3 | var $conf=require('../conf/db.js'); 4 | var $util=require('../util/util.js'); 5 | var $sql=require('./goodsql.js'); 6 | //使用连接池 7 | var pool = mysql.createPool($util.extend({}, $conf.mysql)); 8 | 9 | // 向前台返回JSON方法的简单封装 10 | var jsonWrite = function (res, ret) { 11 | if(typeof ret === 'undefined') { 12 | res.json({ 13 | code:'1', 14 | msg: '操作失败' 15 | }); 16 | } else { 17 | res.json(ret); 18 | } 19 | }; 20 | 21 | module.exports = { 22 | //增加商品 23 | goodadd: function (req, res, next) { 24 | pool.getConnection(function(err, connection) { 25 | // 获取前台页面传过来的参数 26 | var param = req.query || req.params; 27 | 28 | // 建立连接,向表中插入值 29 | // 'INSERT INTO user(id, name, age) VALUES(0,?,?)', 30 | connection.query($sql.goodinsert, [param.name, param.desc,param.price,param.sum], function(err, result) { 31 | if(result) { 32 | result = { 33 | code: 200, 34 | msg:'增加成功' 35 | }; 36 | } 37 | 38 | // 以json形式,把操作结果返回给前台页面 39 | jsonWrite(res, result); 40 | 41 | // 释放连接 42 | connection.release(); 43 | }); 44 | }); 45 | }, 46 | gooddelete: function (req, res, next) { 47 | // delete by Id 48 | pool.getConnection(function(err, connection) { 49 | var id = +req.query.id; 50 | connection.query($sql.gooddelete, id, function(err, result) { 51 | if(result.affectedRows > 0) { 52 | result = { 53 | code: 200, 54 | msg:'删除成功' 55 | }; 56 | } else { 57 | result = void 0; 58 | } 59 | jsonWrite(res, result); 60 | connection.release(); 61 | }); 62 | }); 63 | }, 64 | goodupdate: function (req, res, next) { 65 | // update by id 66 | // 为了简单,要求同时传name和age两个参数 67 | pool.getConnection(function(err, connection) { 68 | // 获取前台页面传过来的参数 69 | var param = req.query || req.params; 70 | 71 | // 建立连接,向表中插入值 72 | // 'INSERT INTO user(id, name, age) VALUES(0,?,?)', 73 | connection.query($sql.goodupdate, [param.name, param.desc,param.price,param.sum,param.id], function(err, result) { 74 | if(result) { 75 | result = { 76 | code: 200, 77 | msg:'修改成功' 78 | }; 79 | } 80 | 81 | // 以json形式,把操作结果返回给前台页面 82 | jsonWrite(res, result); 83 | 84 | // 释放连接 85 | connection.release(); 86 | }); 87 | }); 88 | }, 89 | //得到所有商品 在路由routes调用本方法,这个方法调用sql语句 ,并返回相应结果jsonwrite 90 | goodAll: function (req, res, next) { 91 | pool.getConnection(function(err, connection) { 92 | connection.query($sql.goodAll, function(err, result) { 93 | jsonWrite(res, result); 94 | connection.release(); 95 | }); 96 | }); 97 | }, 98 | 99 | goodById: function (req, res, next) { 100 | var id = +req.query.id; // 为了拼凑正确的sql语句,这里要转下整数 101 | pool.getConnection(function(err, connection) { 102 | connection.query($sql.goodById, id, function(err, result) { 103 | jsonWrite(res, result); 104 | connection.release(); 105 | 106 | }); 107 | }); 108 | }, 109 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nodejs服务端开发(Express+Mysql) # 2 | ## 项目展示 ## 3 | 4 | 1、可以在github下载:[https://github.com/htmlk/express](https://github.com/htmlk/express "https://github.com/htmlk/express") 5 | 6 | ``` 7 | 8 | git clone git@github.com:htmlk/express.git 9 | ``` 10 | 11 | 2、再导入express.sql到数据库,数据库名test,表名:good 结构如下 12 | 13 | ![](http://i.imgur.com/6hfrMJp.png) 14 | 15 | 3、直接run:npm start就能使用了! 16 | 17 | ``` 18 | 19 | npm start 20 | 21 | ``` 22 | 23 | 3、最好自己重新建一遍,才能更好适配自己的需求!下面有详细步骤 24 | ## 项目开发 ## 25 | ### 1、官网下载 nodejs(带npm包管理器)和 git; ### 26 | 27 | ``` 28 | 29 | //npm版本3.3.12 30 | npm -v 31 | //node版本v5.2.0 32 | node -v 33 | ``` 34 | ### 2、使用git,通过npm包管理器,安装express 和express种子生成器(express-generator 生成目录文件); ### 35 | 36 | ``` 37 | 38 | //express 39 | cnpm i express -g 40 | 41 | //express-generator 42 | npm install express-generator -g 43 | 44 | //生成项目文件 45 | express nodeproject 46 | 47 | ``` 48 | 49 | /bin: 用于应用启动 50 | 51 | /public: 静态资源目录 52 | 53 | /routes:可以认为是controller(控制器)目录 54 | 55 | /views: jade模板目录,可以认为是view(视图)目录 56 | 57 | app.js 程序main文件 58 | 59 | 目录结构 60 | 61 | ![](http://i.imgur.com/EsIhUZK.png) 62 | 63 | ### 3、启动express项目 ### 64 | 65 | ``` 66 | npm start 67 | 68 | ``` 69 | 70 | 通过localhost就可以访问了 71 | 72 | ### 4、新建mysql建表 ### 73 | 路由信息新建一个conf文件夹,再新建db.js 74 | 表名:test 75 | (可以将本项目的express.sql导入在mysql数据库中) 76 | ![](http://i.imgur.com/6hfrMJp.png) 77 | 78 | ### 5、接口说明 ### 79 | 80 | 通过id删除商品:http://localhost:3100/goodDel?id=115 81 | 82 | 添加商品:http://localhost:3100/goodAdd? 83 | name=123&desc=123&price=123&sum=234 84 | 85 | 通过id修改商品:http://localhost:3100/goodUpdate?name=123&desc=2313&price=12&sum=12&id=1 86 | 87 | 查询所有商品:http://localhost:3000/goodAll 88 | 89 | 查询单个商品:http://localhost:3100/goodById?id=112 90 | 91 | ### 6、程序运行思路 ### 92 | 93 | 1、浏览器访问地址(localhsot)访问路由文件/routes下的index.js 94 | 95 | ``` 96 | var express = require('express'); 97 | var router = express.Router(); 98 | //关联主程序 99 | var goodlist = require('../good/goodlist.js'); 100 | 101 | /* GET home page. */ 102 | //进入主页面信息 103 | router.get('/', function(req, res, next) { 104 | res.render('index', { title: 'Express' }); 105 | }); 106 | 107 | //增 108 | router.get('/goodAdd',function(req,res,next){ 109 | goodlist.goodadd(req,res,next); 110 | }); 111 | 112 | //删 113 | router.get('/goodDel',function(req,res,next){ 114 | goodlist.gooddelete(req,res,next); 115 | }); 116 | //改 117 | router.get('/goodUpdate',function(req,res,next){ 118 | goodlist.goodupdate(req,res,next); 119 | }); 120 | //查 121 | router.get('/goodAll',function(req,res,next){ 122 | goodlist.goodAll(req,res,next); 123 | }); 124 | router.get('/goodById',function(req,res,next){ 125 | goodlist.goodById(req,res,next); 126 | }); 127 | 128 | module.exports = router; 129 | ``` 130 | 2、访问localhost/goodAll进入查询全部商品路由,路由调用goodlist里的方法goodAll (注意:把goodlist导入进来goodlist.js) 131 | 132 | ``` 133 | 134 | //得到所有商品 在路由routes调用本方法, 135 | goodAll: function (req, res, next) { 136 | pool.getConnection(function(err, connection) { 137 | connection.query($sql.goodAll, function(err, result) { 138 | jsonWrite(res, result); 139 | connection.release(); 140 | }); 141 | }); 142 | } 143 | 144 | ``` 145 | 3、这个方法调用goodsql.js里面的sql语句 ,并返回相应结果jsonwrite 146 | ``` 147 | 148 | var good={ 149 | //增 150 | goodinsert:'INSERT INTO `good` (`id`,`name`,`desc`,`price`,`sum`) VALUES(0,?,?,?,?)', 151 | //删 152 | gooddelete: 'delete from good where id=?', 153 | //改 154 | goodupdate:'UPDATE `good` SET `name`=?,`desc`=?,`price`=?,`sum`=? WHERE `id`=?', 155 | //查 156 | goodAll: 'select * from good', 157 | goodById: 'select * from good where id=?' 158 | } 159 | 160 | module.exports=good; 161 | ``` 162 | ###解决问题### 163 | 1、解决跨域问题(在app.js里面添加) 164 | ``` 165 | //设置跨域访问 166 | app.all('*', function(req, res, next) { 167 |    res.header("Access-Control-Allow-Origin", "*");//*表示允许的域名地址,本地则为'http://localhost' 168 | res.header("Access-Control-Allow-Headers", "X-Requested-With"); 169 | res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); 170 | res.header("X-Powered-By",' 3.2.1') 171 | res.header("Content-Type", "application/json;charset=utf-8"); 172 | next(); 173 | }); 174 | ``` 175 | 176 | 2、拼凑sql语句 177 | 178 | var id = +req.query.id; // 为了拼凑正确的sql语句,这里要转下整数 179 | --------------------------------------------------------------------------------