详解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 相关文章推荐
jquery下为Event handler传递动态参数的代码
Jan 06 Javascript
javascript history对象(历史记录)使用方法(实现浏览器前进后退)
Jan 07 Javascript
jquery 实现返回顶部功能
Nov 17 Javascript
node.js中的path.normalize方法使用说明
Dec 08 Javascript
jQuery中nextUntil()方法用法实例
Jan 07 Javascript
JavaScript获取页面中超链接数量的方法
Nov 09 Javascript
JavaScript获取各大浏览器信息图示
Nov 20 Javascript
JavaScript模版引擎的基本实现方法浅析
Feb 15 Javascript
利用百度地图API获取当前位置信息的实例
Nov 06 Javascript
详解vue-cli脚手架中webpack配置方法
Aug 22 Javascript
vue-cli 项目打包完成后运行文件路径报错问题
Jul 19 Javascript
何时使用Map来代替普通的JS对象
Apr 29 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
Body是什么,该怎么喝出咖啡里的口感
2021/03/03 咖啡文化
解析array splice的移除数组中指定键的值,返回一个新的数组
2013/07/02 PHP
PHP入门教程之面向对象的特性分析(继承,多态,接口,抽象类,抽象方法等)
2016/09/11 PHP
在php7中MongoDB实现模糊查询的方法详解
2017/05/03 PHP
再谈Yii Framework框架中的事件event原理与应用
2020/04/07 PHP
关于scrollLeft,scrollTop的浏览器兼容性测试
2013/03/19 Javascript
Jquery中LigerUi的弹出编辑框(实现方法)
2013/07/09 Javascript
JavaScript利用正则表达式去除日期中的“-”
2014/07/01 Javascript
js网页右下角提示框实例
2014/10/14 Javascript
node.js express中app.param的用法详解
2017/07/16 Javascript
React操作真实DOM实现动态吸底部的示例
2017/10/23 Javascript
webpack多页面开发实践
2017/12/18 Javascript
利用JS动态生成隔行换色HTML表格的两种方法
2018/10/09 Javascript
vue中el-upload上传图片到七牛的示例代码
2018/10/19 Javascript
JS实现动态无缝轮播
2020/01/11 Javascript
jquery实现点击弹出对话框
2020/02/08 jQuery
[09:33]2015国际邀请赛第四日TOP10
2015/08/08 DOTA
python解析xml文件实例分享
2013/12/04 Python
python函数式编程学习之yield表达式形式详解
2018/03/25 Python
Python 中包/模块的 `import` 操作代码
2019/04/22 Python
Python Matplotlib 基于networkx画关系网络图
2019/07/10 Python
python中tkinter的应用:修改字体的实例讲解
2019/07/17 Python
Python实用库 PrettyTable 学习笔记
2019/08/06 Python
Python使用Matlab命令过程解析
2020/06/04 Python
纯css3实现的竖形无限级导航
2014/12/10 HTML / CSS
html5 Canvas实现图片旋转的示例
2018/01/15 HTML / CSS
全球最大的在线旅游公司:Expedia
2017/11/16 全球购物
Theory美国官网:后现代都市风时装品牌
2018/05/09 全球购物
小学生自我评价范例
2013/09/24 职场文书
纺织工程专业个人求职信范文
2014/01/27 职场文书
信息总监管理职责范本
2014/03/08 职场文书
捐助倡议书范文
2014/04/15 职场文书
团委竞选演讲稿
2014/04/24 职场文书
2016年大学生暑假爱心支教活动策划书
2015/11/26 职场文书
2019关于垃圾分类处理的调查报告
2019/12/26 职场文书
Python面向对象编程之类的概念
2021/11/01 Python