前言
要用到express和mongoose
项目目录结构(选)
* bin/www 启动运行(服务端口设置等)
* app.js 整个项目的入口文件
* routes 对各个路由做处理的代码逻辑
* models 数据库的常用操作及配置app.js文件代码解读
app对象的功能:
是为了使用一些具有特定功能的函数( 这些函数我们给起了一个名字 , 叫做中间件 )
我们通过app.use(两个参数:路径,回调) 来使用这些中间件
var index = require('./routes/index'); // 声明要访问的路由
var app = express(); // 重要
app.use('/', index); // 访问已定义的路由文件
module.exports = app; // 抛出 app 变量方法(为 bin 中端口设置做准备)再来看看bin文件夹
// bin/invoice-server
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
const port = parseInt(val, 10);
if (isNaN(port)) {
return val;
}
if (port >= 0) {
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
const bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
const addr = server.address();
const bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
// ~~~ 前面都不用改动 ~~~
/**
* Module dependencies.
*/
const app = require('../app'); // 与前面说的“抛出 app 变量方法(为 bin 中端口设置做准备)”呼应
const debug = require('debug')('server:server'); // 为项目添加DEBUG环境变量,其中第一个server为我们设置 DEBUG 环境变量的值
const http = require('http'); // 提供 httpServer 服务模块,不可少
/**
* Get port from environment and store in Express.
*/
const port = normalizePort(process.env.PORT || '8976'); // 声明端口, 不可少
app.set('port', port); // 绑定端口
/**
* Create HTTP server.
*/
const server = http.createServer(app); // 使用 定义的 http 服务, 不可少
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port); // 监听端口
server.on('error', onError);
server.on('listening', onListening);express作用
是Node.js的核心框架,可以帮助我们快速构建web服务器 / api服务器
Express相对于原生的http模块提供了2个核心功能:静态文件 | 路由处理
mongoose作用
mongoose是nodeJS提供连接 mongodb的一个库
写一个查询接口
mongoose连接数据库
2. models中用mongoose的schema和model操作数据库
定义一个schema
Mongoose 的一切始于 Schema
每个 schema 都会映射到一个 MongoDB collection ,并定义这个collection里的文档的构成
Models
Models 是从 Schema 编译来的构造函数。 它的实例就是可以从数据库保存和读取的文档。
从数据库创建和读取 document 的所有操作都是通过 model 进行的。
PS:schema和model可以理解为继承的关系
简单的示例:
var schema = new mongoose.Schema({ name: 'string', size: 'string' });
var Tank = mongoose.model('Tank', schema); // 把 schema 转换为一个 Model(创建Model) - 第一个参数是跟 model 对应的集合( collection )名字的
单数形式, Mongoose 会自动找到名称是 model 名字复数形式的 collection - demo中Tank 这个 model 就对应数据库中 tanks 这个 collection
- .model() 这个函数其实是对 schema 做了拷贝(生成了 Model)
关于model()方法的第三个参数,可能会遇到一点坑(终端上访问数据库可能会没有相关的collection)
查阅了官方文档才知道,当没有传递collection参数时,Mongoose通过将模型名称传递给utils.toCollectionName方法来生成集合名称,可以通过下面文档给出的demo设置自己的schema集合名称:
3. routes里用express+mongoose具体实现查询
//查询列表
router.post("/list", function (req, res, next) {
const {
pageNum,
pageSize,
_userinfo = {},
...rest
} = req.body;
const params = { ...rest }; // 查询参数
const skip = (pageNum - 1) * pageSize; // 第pageNum页开始记录条数
// .find(conditions, [projection], [options], [callback]) 查找文档
// 在发送命令之前,将conditions参数(条件)转换为各自的模式类型
const model = Configs.find(params).skip(skip).limit(pageSize);
const sortConfig = {
createAt: -1
};
model.sort(sortConfig);
model.exec(function (err, doc) { // .exec() 明确查询结果,第一个参数永远是err,第二个参数是返回的数据
if (err) {
res.json({
success: false,
msg: err.message
});
} else {
// .aggregate([pipeline], [callback]) 对Model集合执行聚合,也就是重整
// pipeline 是一个数组 将管道聚合为对象数组
// aggregate()不触发任何中间件
Configs.aggregate([
{
$match: {...params} // 条件筛选关键词
},
{
$group: { // 分组
_id: null,
total: { $sum: 1 }
}
}
], function (err2, doc2) { // 参数callback如果传递回调,则执行聚合并返回Promise;如果没有传递回调,则返回聚合本身。
Configs.find({}, function (err3, doc3) {
if(err){
res.json({
success: false,
msg: err.message
});
} else {
if (err2) {
res.json({
success: false,
msg: err2.message
});
} else {
res.json({
success: true,
msg:'',
result:{
list: doc, // doc打印结果见下面的图
pageNum,
total: doc2[0] ? doc2[0].total : 0
}
});
}
}
})
});
}
});
});打印一下req.body,可以看到前端发过来的请求数据:
浏览器中向后端发送的确实也是这些数据:
doc打印结果:
也即数据库里存储的数据: