详解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中的Math.ceil() 、Math.floor() 、Math.round() 三个函数的理解
Apr 29 Javascript
jQuery中parentsUntil()方法用法实例
Jan 07 Javascript
javascript函数特点实例分析
May 14 Javascript
js遍历获取表格内数据的方法(必看)
Apr 06 Javascript
微信小程序 开发之全局配置
May 05 Javascript
深入理解Angular4中的依赖注入
Jun 07 Javascript
JS改变页面颜色源码分享
Feb 24 Javascript
vue单页缓存方案分析及实现
Sep 25 Javascript
socket io与vue-cli的结合使用的示例代码
Nov 01 Javascript
Vue.js 实现地址管理页面思路详解(地址添加、编辑、删除和设置默认地址)
Dec 11 Javascript
基于Element的组件改造的树形选择器(树形下拉框)
Feb 27 Javascript
一百多行代码实现react拖拽hooks
Mar 23 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操作数组相关函数
2011/02/03 PHP
PHP+javascript制作带提示的验证码源码分享
2014/05/28 PHP
PHP使用JSON和将json还原成数组
2015/02/12 PHP
PHP几个实用自定义函数小结
2016/01/25 PHP
PHP文件缓存smarty模板应用实例分析
2016/02/26 PHP
php实现和c#一致的DES加密解密实例
2017/07/24 PHP
javascript 获取页面的高度及滚动条的位置的代码
2010/05/06 Javascript
解决Jquery load()加载GB2312页面时出现乱码的两种方案
2013/09/10 Javascript
jQuery实现强制cookie过期方法汇总
2015/05/22 Javascript
request请求获取参数的实现方法(post和get两种方式)
2016/09/27 Javascript
jQuery使用bind函数实现绑定多个事件的方法
2017/10/11 jQuery
layer.close()关闭进度条和Iframe窗的方法
2018/08/17 Javascript
JavaScript实现美化滑块效果
2019/05/17 Javascript
Vue的路由及路由钩子函数的实现
2019/07/02 Javascript
vue axios封装httpjs,接口公用配置拦截操作
2020/08/11 Javascript
关于vue-cli3打包代码后白屏的解决方案
2020/09/02 Javascript
Antd表格滚动 宽度自适应 不换行的实例
2020/10/27 Javascript
在Django的通用视图中处理Context的方法
2015/07/21 Python
Python爬虫获取图片并下载保存至本地的实例
2018/06/01 Python
全面解析CSS Media媒体查询使用操作(推荐)
2017/08/15 HTML / CSS
HTML5 Convas APIs方法详解
2015/04/24 HTML / CSS
药学专业大专生的自我评价
2013/12/12 职场文书
个人作风剖析材料
2014/02/02 职场文书
《大禹治水》教学反思
2014/04/27 职场文书
2014年秋季开学典礼致辞
2014/08/02 职场文书
教师自我剖析材料
2014/09/29 职场文书
2014年前台文员工作总结
2014/12/08 职场文书
乌镇导游词
2015/02/02 职场文书
投标邀请书范本
2015/02/02 职场文书
2015年机关党建工作总结
2015/05/22 职场文书
2015年学校医务室工作总结
2015/07/20 职场文书
2015年卫生局工作总结
2015/07/24 职场文书
婚宴新娘致辞
2015/07/28 职场文书
面试被问select......for update会锁表还是锁行
2021/11/11 MySQL
Oracle配置dblink访问PostgreSQL的操作方法
2022/03/21 PostgreSQL
基于Python实现对比Exce的工具
2022/04/07 Python