详解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深入理解js闭包
Jul 03 Javascript
jQuery操作input值的各种方法总结
Nov 21 Javascript
使用jQuery管理选择结果
Jan 20 Javascript
js获取html的span标签的值方法(超简单)
Jul 26 Javascript
JS实战篇之收缩菜单表单布局
Dec 10 Javascript
微信小程序 template模板详解及实例代码
Mar 09 Javascript
vue给input file绑定函数获取当前上传的对象完美实现方法
Dec 15 Javascript
JS实现延迟隐藏功能的方法(类似QQ头像鼠标放上展示信息)
Dec 28 Javascript
vue单页面打包文件大?首次加载慢?nginx带你飞,从7.5M到1.3M蜕变过程(推荐)
Jan 16 Javascript
在vue项目中引入vue-beauty操作方法
Feb 11 Javascript
微信小程序实现获取准确的腾讯定位地址功能示例
Mar 27 Javascript
手把手15分钟搭一个企业级脚手架
Sep 16 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
虫族 Zerg 魔法科技
2020/03/14 星际争霸
Laravel框架集成UEditor编辑器的方法图文与实例详解
2019/04/17 PHP
js实现漂浮回顶部按钮实例
2015/05/06 Javascript
通过点击jqgrid表格弹出需要的表格数据
2015/12/02 Javascript
JS函数arguments数组获得实际传参数个数的实现方法
2016/05/28 Javascript
10分钟掌握XML、JSON及其解析
2020/12/06 Javascript
Vue.js基础知识小结
2017/01/13 Javascript
jQuery基本选择器和层次选择器学习使用
2017/02/27 Javascript
js中toString()和String()区别详解
2017/03/23 Javascript
微信小程序使用Promise简化回调
2018/02/06 Javascript
如何使用less实现随机下雪动画详解
2019/01/02 Javascript
layui type2 通过url给iframe子页面传值的例子
2019/09/06 Javascript
JavaScript仿京东秒杀倒计时
2020/03/17 Javascript
JavaScript监听一个DOM元素大小变化
2020/04/26 Javascript
微信小程序中的列表切换功能实例代码详解
2020/06/09 Javascript
JavaScript实现点击图片换背景
2020/11/20 Javascript
[01:05:00]2018国际邀请赛 表演赛 Pain vs OpenAI
2018/08/24 DOTA
用python 制作图片转pdf工具
2015/01/30 Python
Python单例模式实例详解
2017/03/01 Python
Python动刷新抢12306火车票的代码(附源码)
2018/01/24 Python
详解TensorFlow在windows上安装与简单示例
2018/03/05 Python
Python排序算法之选择排序定义与用法示例
2018/04/29 Python
python读取TXT每行,并存到LIST中的方法
2018/10/26 Python
使用Python和Prometheus跟踪天气的使用方法
2019/05/06 Python
python在OpenCV里实现投影变换效果
2019/08/30 Python
python实现宿舍管理系统
2019/11/22 Python
Django中使用Json返回数据的实现方法
2020/06/03 Python
html5 视频播放解决方案
2016/11/06 HTML / CSS
Spartoo葡萄牙鞋类网站:线上销售鞋履与时尚配饰
2017/01/11 全球购物
澳大利亚游乐场设备品牌:Lifespan Kids
2019/05/24 全球购物
简述进程的启动、终止的方式以及如何进行进程的查看
2014/02/20 面试题
如何写自我评价?自我评价写什么好?
2014/03/14 职场文书
企业年会主持词
2014/03/27 职场文书
2015年学校教务处工作总结
2015/05/11 职场文书
清明扫墓感想
2015/08/11 职场文书
酒吧七夕情人节宣传语
2015/11/24 职场文书