详解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 相关文章推荐
JavaScipt基本教程之前言
Jan 16 Javascript
使用jQuery validate 验证注册表单实例演示
Mar 25 Javascript
JS关闭窗口与JS关闭页面的几种方法小结
Dec 17 Javascript
jquery.post用法关于type设置问题补充
Jan 03 Javascript
使用ajax+jqtransform实现动态加载select
Dec 01 Javascript
javascript递归回溯法解八皇后问题
Apr 22 Javascript
javascript基本算法汇总
Mar 09 Javascript
js自调用匿名函数的三种写法(推荐)
Aug 19 Javascript
Vue.js表单控件实践
Oct 27 Javascript
jquery 手势密码插件
Mar 17 Javascript
使用Electron构建React+Webpack桌面应用的方法
Dec 15 Javascript
原生js实现移动端触摸轮播的示例代码
Dec 22 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
我的论坛源代码(一)
2006/10/09 PHP
PHP连接Nginx服务器并解析Nginx日志的方法
2015/08/16 PHP
PHP实现对二维数组某个键排序的方法
2016/09/14 PHP
PHP编程中的Session阻塞问题与解决方法分析
2017/08/07 PHP
js实现兼容IE6与IE7的DIV高度
2010/05/13 Javascript
基于jquery的下拉框改变动态添加和删除表格实现代码
2020/09/12 Javascript
打豆豆小游戏 用javascript编写的[打豆豆]小游戏
2013/01/08 Javascript
Javascript 读取操作Sql中的Xml字段
2014/10/09 Javascript
js实现点击链接后窗口缩小并居中的方法
2015/03/02 Javascript
javascript实现类似于新浪微博搜索框弹出效果的方法
2015/07/27 Javascript
基于nodejs+express(4.x+)实现文件上传功能
2015/11/23 NodeJs
Jquery和Js获得元素标签名称的方法总结
2016/10/08 Javascript
jQuery网页定位导航特效实现方法
2016/12/19 Javascript
简单实现js进度条加载效果
2020/03/25 Javascript
js制作简单的音乐播放器的示例代码
2017/08/28 Javascript
详解如何优雅地在React项目中使用Redux
2017/12/28 Javascript
关于Google发布的JavaScript代码规范你要知道哪些
2018/04/04 Javascript
es6基础学习之解构赋值
2018/12/10 Javascript
vue项目中引入Sass实例方法
2019/08/27 Javascript
详解vue-router的Import异步加载模块问题的解决方案
2020/05/13 Javascript
[58:23]LGD vs TNC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
django 按时间范围查询数据库实例代码
2018/02/11 Python
使用python进行波形及频谱绘制的方法
2019/06/17 Python
Flask使用Pyecharts在单个页面展示多个图表的方法
2019/08/05 Python
Pandas 缺失数据处理的实现
2019/11/04 Python
Python中关于logging模块的学习笔记
2020/06/03 Python
python属于跨平台语言码
2020/06/09 Python
联想法国官方网站:Lenovo法国
2018/10/18 全球购物
Nixon手表英国官网:美国尼克松手表品牌
2020/02/10 全球购物
HashMap和Hashtable的区别
2013/05/18 面试题
高中生毕业学习总结的自我评价
2013/11/14 职场文书
自我查摆剖析材料
2014/10/11 职场文书
休学证明范本
2015/06/19 职场文书
委托开发合同书(标准版)
2019/08/07 职场文书
python实现求纯色彩图像的边框
2021/04/08 Python
golang内置函数len的小技巧
2021/07/25 Golang