详解Node.js模块间共享数据库连接的方法


Posted in Javascript onMay 24, 2016

这个标题本身就是一个命题,因为使用默认方式的情况下,一个 Node.js 应用里的各个模块都是共享的同一个数据库连接。但是如果姿势不对,可能会很丑陋,甚至可能会出错。

你可以忽略下面这部分,直接切入正题。

背景
最近在做专业课程设计,题目是“机票预订管理系统”。需求比较简单,就试着拿最近在学的 Node.js 来做了。本来还在调研用何种 Node.js 框架比较合适,看了几个框架之后发现这是杀鸡用牛刀,有看文档查资料的时间还不如直接动手写了。最后写完我会把代码放到 Github 上,欢迎大家批评指正。

数据库方面,以为我比较熟悉和喜欢 JSON (SQL 没学好就承认呗-_-#),所以就选择了 MongoDB。Node + Mongo 是近几年越来越热门的后端组合,网上有很多关于如何一起使用的资料。但为了节约时间(课程设计也就一个多星期),把精力多集中在系统和逻辑上,我用了 Mongoose 这个专门用于 MongoDB 数据建模的 Node.js 扩展,用它来大大减少操作数据库的代码。

正题
我建立了两个数据模型(Model),一个是用户(User),一个是航班(Flight),分别封装到了 user.js, flight.js 这两个模块(Module)里面。Model 专门负责和数据库交互,用户和航班这两个模块都需要连接数据库,一开始我的代码是这样的:

// ----- user.js -----
// require mongoose.js 引用mongoose.js
var M = require('mongoose');
// connect to database 连接数据库
M.connect('mongodb://localhost/test');
// ... some other code ...

// ----- flight.js -----
// require mongoose.js 引用mongoose.js
var M = require('mongoose');
// connect to database 连接数据库
M.connect('mongodb://localhost/test');
// ... some other code ...

// ----- models.js -----
var user = require('./user'),
  flight = require('./flight');

// ----- index.js -----
var Models = require('./models');

且不说这种写法一点都不 DRY,这种方式本身就是错误的。当我运行 index.js 时,会出现如下错误。

> node index.js
> Connection error: { [Error: Trying to open unclosed connection.] state: 2 }

错误是:尝试打开未关闭的连接。

所以我们应该在一个地方连接一次数据库,然后其他需要连接数据库的模块通过这个模块来和数据库交互。就好像插线板,义无反顾地吼叫道:“墙上就一个插座,你们不要抢了!放着我来!你们。。。就可以了!”

具体方案
我们把连接数据库的动作放到一个模块里,并且把连接暴露给整个应用中的其他模块,然后其他需要连接数据库的模块引用这个连接即可。

// ----- database.js -----
var M = require('mongoose');
M.connect('mongodb://localhost/test');
// reference to the database connection 为这个连接创建一个引用
var db = M.connection;
// expose to modules that require database.js 把这个引用暴露给引用 database 模块的其他模块
module.exports = db;

// ----- user.js ----- flight.js 类似 -----
// ... some other code ...
// 我们会在 models.js 中,把数据库连接的引用作为参数传进来
module.exports = function( db ){
  if( db ){
    // ... do things with the connection ... 如果连接了数据库,就可以执行数据库相关的操作了
  }
}

// ----- models.js -----
// require database module, retrieve the reference to database connection 引用 databse 模块,获取数据库连接的引用
var db = require('./database');
// 把数据库连接的引用传入需要连接数据库的模块,任务完成!
var user = require('./user')( db ),
  flight = require('./flight')( db );

这就是让一个 Node.js 应用的多个模块共享数据库连接的一种方法。是我在 StackOverflow 上面看到的。如果你有更好的方法,欢迎在评论中分享给大家!

Javascript 相关文章推荐
Javascript 继承实现例子
Aug 12 Javascript
JavaScript 学习技巧
Feb 17 Javascript
Javascript基础教程之关键字和保留字汇总
Jan 18 Javascript
JavaScript计算两个日期时间段内日期的方法
Mar 16 Javascript
jQuery实现垂直半透明手风琴特效代码分享
Aug 21 Javascript
avalon js实现仿google plus图片多张拖动排序附源码下载
Sep 24 Javascript
BOM之navigator对象和用户代理检测
Feb 10 Javascript
vue2.0 移动端实现下拉刷新和上拉加载更多的示例
Apr 23 Javascript
vue 本地环境跨域请求proxyTable的方法
Sep 19 Javascript
详解vue微信网页授权最终解决方案
Jun 16 Javascript
ES6中let、const的区别及变量的解构赋值操作方法实例分析
Oct 15 Javascript
vue使用微信扫一扫功能的实现代码
Apr 11 Javascript
轻松掌握jQuery中wrap()与unwrap()函数的用法
May 24 #Javascript
使用jQuery中的wrap()函数操作HTML元素的教程
May 24 #Javascript
实例解析jQuery中proxy()函数的用法
May 24 #Javascript
jQuery前端开发35个小技巧
May 24 #Javascript
JS+Canvas绘制时钟效果
Aug 20 #Javascript
基于JQuery实现图片上传预览与删除操作
May 24 #Javascript
JavaScript仿淘宝页面图片滚动加载及刷新回顶部的方法解析
May 24 #Javascript
You might like
PHP循环遍历数组的3种方法list()、each()和while总结
2014/11/19 PHP
php通过淘宝API查询IP地址归属等信息
2015/12/25 PHP
PHP中类型转换 ,常量,系统常量,魔术常量的详解
2017/10/26 PHP
php读取本地json文件的实例
2018/03/07 PHP
Firefox和IE浏览器兼容JS脚本写法小结
2008/07/07 Javascript
JavaScript 高效运行代码分析
2010/03/18 Javascript
Ext JS 4官方文档之三 -- 类体系概述与实践
2012/12/16 Javascript
两个listbox实现选项的添加删除和搜索
2013/03/01 Javascript
javascript的内存管理详解
2013/08/07 Javascript
Json和Jsonp理论实例代码详解
2013/11/15 Javascript
Javascript 修改String 对象 增加去除空格功能(示例代码)
2013/11/30 Javascript
Vue2.0用户权限控制解决方案的示例
2018/02/10 Javascript
create-react-app 修改为多入口编译的方法
2018/08/01 Javascript
ES6 Object属性新的写法实例小结
2019/06/25 Javascript
Js图片点击切换轮播实现代码
2020/07/27 Javascript
[02:09]2018DOTA2亚洲邀请赛TNC赛前采访
2018/04/04 DOTA
python写的ARP攻击代码实例
2014/06/04 Python
仅利用30行Python代码来展示X算法
2015/04/01 Python
Python中使用PDB库调试程序
2015/04/05 Python
总结python实现父类调用两种方法的不同
2017/01/15 Python
pandas的object对象转时间对象的方法
2018/04/11 Python
python和opencv实现抠图
2018/07/18 Python
python 自动去除空行的实例
2018/07/24 Python
python实现一组典型数据格式转换
2018/12/15 Python
python 处理telnet返回的More,以及get想要的那个参数方法
2019/02/14 Python
Django url,从一个页面调到另个页面的方法
2019/08/21 Python
python 解决mysql where in 对列表(list,,array)问题
2020/06/06 Python
python使用自定义钉钉机器人的示例代码
2020/06/24 Python
台湾流行服饰购物平台:OB严选
2018/01/21 全球购物
中专三年学习的个人自我评价
2013/12/12 职场文书
社会实践心得体会
2014/01/03 职场文书
经贸专业毕业生求职信
2014/03/23 职场文书
一份文言文检讨书
2014/09/13 职场文书
餐饮服务员岗位职责
2015/02/09 职场文书
大学宣传委员竞选稿
2015/11/19 职场文书
2016年世界人口日宣传活动总结
2016/04/05 职场文书