详解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中的Array数组对象详谈
Mar 03 Javascript
离开当前页面前使用js判断条件提示是否要离开页面
May 02 Javascript
JQuery中$(document)是什么意思有什么作用
Jul 21 Javascript
js读取cookie方法总结
Oct 31 Javascript
聊一聊JavaScript作用域和作用域链
May 03 Javascript
jqueryUI tab标签页代码分享
Oct 09 jQuery
微信小程序App生命周期详解
Jan 31 Javascript
D3.js实现简洁实用的动态仪表盘的示例
Apr 04 Javascript
vue项目开发中setTimeout等定时器的管理问题
Sep 13 Javascript
JS实现瀑布流效果
Mar 07 Javascript
Vue如何基于vue-i18n实现多国语言兼容
Jul 17 Javascript
JavaScript原始值与包装对象的详细介绍
May 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
星际争霸教主Flash的ID由来:你永远不会知道他之前的ID是www!
2019/01/18 星际争霸
手冲咖啡应该是现代精品咖啡店的必备选项吗?
2021/03/03 冲泡冲煮
ThinkPHP实现事务回滚示例代码
2014/06/23 PHP
PHP验证码生成原理和实现
2016/01/24 PHP
在Win2003(64位)中配置IIS6+PHP5.2.17+MySQL5.5的运行环境
2016/04/04 PHP
Yii2中YiiBase自动加载类、引用文件方法分析(autoload)
2016/07/25 PHP
TP5(thinkPHP5框架)实现显示错误信息及行号功能的方法
2019/06/03 PHP
TP框架实现上传一张图片和批量上传图片的方法分析
2020/04/23 PHP
学习ExtJS table布局
2009/10/08 Javascript
动态调用CSS文件的JS代码
2010/07/29 Javascript
兼容FF和IE的动态table示例自写
2013/10/21 Javascript
jquery分割字符串的方法
2015/06/24 Javascript
Javascript中Date类型和Math类型详解
2016/02/27 Javascript
JavaScript高级程序设计(第三版)学习笔记1~5章
2016/03/11 Javascript
基于jquery fly插件实现加入购物车抛物线动画效果
2016/04/05 Javascript
深入理解setTimeout函数和setInterval函数
2016/05/20 Javascript
用JS实现轮播图效果(二)
2016/06/26 Javascript
微信小程序 wxapp地图 map详解
2016/10/31 Javascript
JS实现图片预加载之无序预加载功能代码
2017/05/12 Javascript
JavaScript实现图片无缝滚动效果
2017/07/07 Javascript
使用JS获取页面上的所有标签
2018/10/18 Javascript
js console.log打印对象时属性缺失的解决方法
2019/05/23 Javascript
解决echarts图表使用v-show控制图表显示不全的问题
2020/07/19 Javascript
在vue中实现嵌套页面(iframe)
2020/07/30 Javascript
使用纯前端JavaScript实现Excel导入导出方法过程详解
2020/08/07 Javascript
Python中的类与对象之描述符详解
2015/03/27 Python
Python中线程的MQ消息队列实现以及消息队列的优点解析
2016/06/29 Python
HealthElement海外旗舰店:新西兰大卖场
2018/02/23 全球购物
SOKOLOV官网:俄罗斯珠宝首饰品牌
2021/01/02 全球购物
秋季运动会加油稿200字
2014/01/11 职场文书
软件项目实施计划书
2014/05/02 职场文书
精神文明单位申报材料
2014/05/02 职场文书
勤奋学习演讲稿
2014/05/10 职场文书
文明好少年事迹材料
2014/08/19 职场文书
MySQL学习总结-基础架构概述
2021/04/05 MySQL
一看就懂的MySQL的聚簇索引及聚簇索引是如何长高的
2021/05/25 MySQL