从零开始学习nodejs(五)nodejs+express+mysql搭建后台服务(下)

系列文章github项目地址(最终版):https://github.com/zliuyang1287/MyBlog

接上篇,虽然基本的服务器功能实现了,但是文件过于杂乱,因为是边学边做,所以并没有规范。现在既已知道各个文件作用,也了解了express框架的工作原理,现在就把文件整理一下。

首先最受不了的就是userDao文件,仔细观察其实可以发现,每次操作数据库的步骤是一样的,这里就可以抽取2个公共方法。一个是带返回数据的查询类方法,一个是插入修改删除的方法。可以看到无论各种操作,变的东西只有sql和参数,所以直接抽象出两个方法放到工具类下。为防止工具类持续增多,这里把util.js也干掉,根据工具类型分好类
util文件目录
在这里插入图片描述
DbUtil.js

// 获取连接池
var pool = require('../conf/DbConf');
// 获取json格式化工具类
var json = require('./JsonFormat');
// 执行增删改通用方法
var executeSql = function (res, sql, param) {
    pool.getConnection(function (err, connection) {
        // 捕捉链接错误信息并返回
        if (err) {
            json.rtnError(res, "数据库连接失败:" + err.message);
            return;
        }
        // 执行sql语句,这里是插入一条信息query一共有三个参数,第一个是sql语句。第二个是参数数组,一定要和数据库的
        // 数据类型相对应,也要跟sql语句的占位符相对应。第三个是回调函数,err代表访问是否出错,result代表本次访问的回执信息
        connection.query(sql, param, function (err, result) {
            // 插入失败,返回错误信息
            if (err) {
                json.rtnError(res, err.message);
                return;
            }
            // 插入成功返回操作成功,result可以自己打印看一下,当只做查询时返回查询到的数据,其他诸如增删改操作返回的是一个
            // 对象,其中affectedRows就是受影响的行数,其余的属性可以自行打印看看
            if (result.affectedRows > 0) {
                json.rtnSuccess(res);
            }
            // 释放连接,访问数据库完成一定要及时干掉此次连接请求,不然一会你的数据库就崩死了 
            connection.release();
        });
    });
};

// 数据查询通用方法,param为null表示无参数查询
var queryData = function (res, sql, param) {
    pool.getConnection(function (err, connection) {
        if (err) {
            json.rtnError(res, "数据库连接失败:" + err.message);
            return;
        }
        if (param != null) {
            connection.query(sql, param, function (err, result) {
                if (err) {
                    json.rtnError(res, err.message);
                    return;
                }
                if (result) {
                    // 返回查询结果
                    json.rtnObj(res, result);
                }
            });
        } else {
            connection.query(sql, function (err, result) {
                if (err) {
                    json.rtnError(res, err.message);
                    return;
                }
                if (result) {
                    // 返回查询结果
                    json.rtnObj(res, result);
                }

            });
        }
        // 释放连接
        connection.release();
    });
};
// 提供给dao用
module.exports = { executeSql, queryData };

JsonFormat.js

// 封装返回消息
var rtnSuccess = function (res) {
    var obj = { "code": 0, "msg": "操作成功" }
    res.json(obj);
};
var rtnError = function (res, message) {
    var obj = { "code": 1, "msg": message }
    res.json(obj);
};
var rtnObj = function (res, data) {
    var obj = { "code": 1, "msg": "操作成功", "data": data }
    res.json(obj);
};


module.exports = { rtnError, rtnObj, rtnSuccess };

工具类修改完后,就要对应修改一下UserDao,优化一下逻辑处理,引入封装好的数据库操作工具,调用这里的两个方法代替原来的重复代码
UserDao.js

// 实现与MySQL交互
// 获取json格式化工具类
var json = require('../../util/JsonFormat');
// 获取编写好的sql语句
var sql = require('./User');
// 引入封装好的数据库操作工具
var db = require('../../util/DbUtils');
// 暴露方法给路由处调动
module.exports = {
	//增加
	add: function (req, res, next) {
		// 获取前台页面传过来的参数
		// ps:res和rsp有哪些属性可以去菜鸟教程的express部分查看,或者我在文末附上
		var param = req.query || req.search;
		// 处理判断参数传递的正确与否
		if(param.account==null || param.name==null || param.password==null){
			json.rtnError(res,'账号、密码、用户名都必须填写!');
			return;
		}
		// 条件正确执行插入
		db.executeSql(res,sql.insert,[param.account,param.password,param.name,new Date()]);
	},
	delete: function (req, res, next) {
		var id =req.query.id;
		if(id==null){
			json.rtnError(res,'未获取到要删除的信息!');
			return;
		}
		// 转为int因为这里数据库的id类型是int,否则默认是string类型,会导致报错
		db.executeSql(res,sql.delete,parseInt(id));
	},
	update: function (req, res, next) {
		// 根据id更新账户名、姓名信息
		var param = req.query;
		if(param.account == null || param.id == null || param.name == null) {
			json(res, '更新失败!账户、用户名、用户id均不可为空!');
			return;
		}
		db.executeSql(res,sql.update, [param.account, param.name, parseInt(param.id)]);
	},
	queryById: function (req, res, next) {
		var id = req.query.id; 
		if (id==null) {
			json.rtnError(res,"未获取到要查询的用户id!");
			return;
		}
		db.queryData(res,sql.queryById,parseInt(id));
	},
	queryAll: function (req, res, next) {
		db.queryData(sql.queryAll, null);
	},
	updatePsd: function (req, res, next) {
		var param = req.query || req.search;
		if (param.id == null || param.password == null) {
			json.rtnError(res,"密码修改失败!");
			return;
		}
		db.executeSql(res,sql.updatePsd,[param.password,parseInt(param.id)]);
	}
};

明显感觉清晰多了。

接下来要整理的就是路由了,首先路由必须从app.js拿出来,都放在里面太臃肿。
app.js
这里做如下修改

// 自己编写的模块
// 引入路由
var route = require('./routes/route');

// 设置路由,用于不同的页面之间的切换判断
route(app);

route.js
单独处理路由配置,作为所有路由的总入口

// 路由总配置
// 引入用户路由
var user = require('./UserRoute');
//...还可以引入其他路由,按功能分组
var route = function(app){
    // 以user开头,后面的增删改查动作放到UserRoute,直接以add,delete体现出来,不用addUser,deleteUser之类
    app.use('/user', user);
}

module.exports = route;

UserRoute.js
这里就是用户下所有的功能子路由了,只存放用户相关的

var express = require('express');
var router = express.Router();
// 引入数据库的访问方法,类比Java这里就是注入Service
var userDao = require('../dao/user/UserDao');

//配置路由
// post就是post请求
router.post('/add', function(req, res, next) {
  // 调用userDao中的add方法
	userDao.add(req, res, next);
});
// get请求,习惯上数据添加修改都用post,查询删除用get
router.get('/delete', function(req, res, next) {
	userDao.delete(req, res, next);
});
router.post('/update', function(req, res, next) {
	userDao.update(req, res, next);
});
router.post('/updatePsd', function(req, res, next) {
	userDao.updatePsd(req, res, next);
});
router.get('/queryById', function(req, res, next) {
	userDao.queryById(req, res, next);
});
router.get('/queryAll', function(req, res, next) {
	userDao.queryAll(req, res, next);
});
module.exports = router;

以上就是全部的路由配置了。

完成路由优化后重新保存启动,试一下效果,注意看路由
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一切顺利,别的功能就不试了

到此为止这个后台服务器整体好多了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章