详解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级联操作绑定事件实例
Sep 02 Javascript
js实现DOM走马灯特效的方法
Jan 21 Javascript
jQuery标签编辑插件Tagit使用指南
Apr 21 Javascript
jQuery实现摸拟alert提示框
May 22 Javascript
Angular 理解module和injector,即依赖注入
Sep 07 Javascript
jQuery实现选中行变色效果(实例讲解)
Jul 06 jQuery
React中jquery引用的实现方法
Sep 12 jQuery
JS插件clipboard.js实现一键复制粘贴功能
Dec 04 Javascript
详解vuex之store拆分即多模块状态管理(modules)篇
Nov 13 Javascript
零基础之Node.js搭建API服务器的详解
Mar 08 Javascript
vue项目中使用scss的方法步骤
May 16 Javascript
解决Vue router-link绑定事件不生效的问题
Jul 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
php中echo()和print()、require()和include()等易混淆函数的区别
2012/02/22 PHP
laravel批量生成假数据的方法
2019/10/09 PHP
JS检测图片大小的实例
2013/08/21 Javascript
JavaScript实现简单的时钟实例代码
2013/11/23 Javascript
window.location.href的用法(动态输出跳转)
2014/08/09 Javascript
javascript作用域问题实例分析
2015/07/13 Javascript
基于jQuery实现响应式圆形图片轮播特效
2015/11/25 Javascript
jquery根据td给相同tr下其他td赋值的实现方法
2016/10/05 Javascript
JS中substring与substr的用法
2016/11/16 Javascript
Bootstrap导航条可点击和鼠标悬停显示下拉菜单
2016/11/25 Javascript
jQuery插件HighCharts绘制的基本折线图效果示例【附demo源码下载】
2017/03/07 Javascript
完美实现js焦点轮播效果(二)(图片可滚动)
2017/03/07 Javascript
微信小程序 页面跳转如何实现传值
2017/04/05 Javascript
Express本地测试HTTPS的示例代码
2018/06/06 Javascript
BootStrap中的模态框(modal,弹出层)功能示例代码
2018/11/02 Javascript
node.js制作一个简单的登录拦截器
2020/02/10 Javascript
python计算圆周长、面积、球体体积并画出圆
2014/04/08 Python
python中去空格函数的用法
2014/08/21 Python
Python实现线程池代码分享
2015/06/21 Python
深入理解Python中变量赋值的问题
2017/01/12 Python
Python实现对字符串的加密解密方法示例
2017/04/29 Python
Python 列表理解及使用方法
2017/10/27 Python
朴素贝叶斯Python实例及解析
2018/11/19 Python
python实现按键精灵找色点击功能教程,使用pywin32和Pillow库
2020/06/04 Python
用opencv给图片换背景色的示例代码
2020/07/08 Python
python pandas dataframe 去重函数的具体使用
2020/07/20 Python
Python经纬度坐标转换为距离及角度的实现
2020/11/01 Python
关于探究python中sys.argv时遇到的问题详解
2021/02/23 Python
分享一个页面平滑滚动小技巧(推荐)
2019/10/23 HTML / CSS
HTML5 的新的表单元素(datalist/keygen/output)使用介绍
2013/07/19 HTML / CSS
HTML5 Canvas基本线条绘制的实例教程
2016/03/17 HTML / CSS
出门问问全球官方商城:Tichome音箱和TicWatch智能手表
2017/12/02 全球购物
婚鞋、新娘鞋、礼服鞋、童鞋:Nina Shoes
2019/09/04 全球购物
结构工程个人自荐信范文
2013/11/30 职场文书
2014年纪委工作总结
2014/12/05 职场文书
大学生入党自荐书
2015/03/05 职场文书